Changes most of the VFR handling to ints and clean up stuff
Originally committed to SVN as r96.
This commit is contained in:
parent
cbc7b57669
commit
24a7e9ba91
5 changed files with 165 additions and 352 deletions
|
@ -68,7 +68,7 @@ void AssTransformFramerateFilter::Init() {
|
|||
void AssTransformFramerateFilter::ProcessSubs(AssFile *subs) {
|
||||
// Transform frame rate
|
||||
if (Input->loaded && Output->loaded) {
|
||||
if (Output->FrameRateType == VFR || Output->AverageFrameRate != Input->AverageFrameRate) {
|
||||
if (Output->FrameRateType == 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.AverageFrameRate);
|
||||
if (VFR_Input.loaded) initialInput = wxString::Format(_T("%2.3f"),VFR_Input.GetAverage());
|
||||
else {
|
||||
initialInput = _T("23.976");
|
||||
FromVideo->Enable(false);
|
||||
|
|
|
@ -259,7 +259,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.vfr);
|
||||
MenuBar->Enable(Menu_File_Close_VFR,VFR_Output.loaded && VFR_Output.FrameRateType == VFR); //fix me, wrong?
|
||||
|
||||
// Set AR radio
|
||||
if (videoBox->videoDisplay->arType == 0) MenuBar->Check(Menu_Video_AR_Default,true);
|
||||
|
|
433
core/vfr.cpp
433
core/vfr.cpp
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2005, Rodrigo Braz Monteiro
|
||||
// Copyright (c) 2005-2006, Rodrigo Braz Monteiro, Fredrik Mellbin
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
|
@ -37,175 +37,36 @@
|
|||
///////////
|
||||
// Headers
|
||||
#include "vfr.h"
|
||||
#include "utils.h"
|
||||
#include <wx/filename.h>
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
|
||||
////////////////////// V1 //////////////////////
|
||||
//////////////////
|
||||
// V1 Constructor
|
||||
VFR_v1::VFR_v1 () {
|
||||
Clear();
|
||||
}
|
||||
|
||||
|
||||
/////////////////
|
||||
// V1 Destructor
|
||||
VFR_v1::~VFR_v1 () {
|
||||
Clear();
|
||||
}
|
||||
|
||||
|
||||
/////////////////////
|
||||
// V1 Clear function
|
||||
void VFR_v1::Clear () {
|
||||
Range.clear();
|
||||
}
|
||||
|
||||
|
||||
////////////////
|
||||
// V1 Add range
|
||||
void VFR_v1::AddRange(int start,int end,double fps,bool isdefault) {
|
||||
VFR_v1_Range newRange;
|
||||
newRange.start = start;
|
||||
newRange.end = end;
|
||||
newRange.fps = fps;
|
||||
newRange.isDefault = isdefault;
|
||||
if (isdefault) DefaultFPS = fps;
|
||||
Range.push_back(newRange);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////
|
||||
// V1 Get frame at time
|
||||
int VFR_v1::GetFrameAtTime(int _ms) {
|
||||
double ms = _ms;
|
||||
double curms = 0;
|
||||
double prevms = 0;
|
||||
int curframe = 0;
|
||||
double fpms;
|
||||
for (std::list<VFR_v1_Range>::iterator cur=Range.begin();cur!=Range.end();cur++) {
|
||||
fpms = (*cur).fps/1000.0;
|
||||
curms += double((*cur).end - (*cur).start + 1) / fpms;
|
||||
if (curms > ms) {
|
||||
//return curframe + floor((ms - prevms) * fpms + 0.5);
|
||||
//return curframe + floor((ms - prevms) * fpms);
|
||||
double msValue = (ms - prevms) * fpms;
|
||||
double floorValue = ceil(msValue);
|
||||
int final = curframe + floorValue;
|
||||
return final;
|
||||
}
|
||||
curframe = (*cur).end+1;
|
||||
prevms = curms;
|
||||
}
|
||||
//return curframe + floor((ms - prevms) * DefaultFPS/1000.0 + 0.5);
|
||||
return curframe + floor((ms - prevms) * DefaultFPS/1000.0);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////
|
||||
// V1 Get time at frame
|
||||
int VFR_v1::GetTimeAtFrame(int frame) {
|
||||
double acum = 0;
|
||||
int last = 0;
|
||||
for (std::list<VFR_v1_Range>::iterator cur=Range.begin();cur!=Range.end();cur++) {
|
||||
if (frame <= (*cur).end) {
|
||||
acum += double(frame - (*cur).start) / (*cur).fps;
|
||||
//return floor(acum*1000.0+0.5);
|
||||
return floor(acum*1000.0);
|
||||
}
|
||||
else {
|
||||
acum += double((*cur).end - (*cur).start + 1) / (*cur).fps;
|
||||
last = (*cur).end+1;
|
||||
}
|
||||
}
|
||||
acum += double(frame - last) / DefaultFPS;
|
||||
//return floor(acum*1000.0+0.5);
|
||||
return floor(acum*1000.0);
|
||||
}
|
||||
|
||||
|
||||
//////////////////
|
||||
// V1 Get Average
|
||||
double VFR_v1::GetAverage () {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
////////////////////// V2 //////////////////////
|
||||
//////////////////
|
||||
// V2 Constructor
|
||||
VFR_v2::VFR_v2 () {
|
||||
Clear();
|
||||
}
|
||||
|
||||
|
||||
/////////////////
|
||||
// V2 Destructor
|
||||
VFR_v2::~VFR_v2 () {
|
||||
Clear();
|
||||
}
|
||||
|
||||
|
||||
/////////////////////
|
||||
// V2 Clear function
|
||||
void VFR_v2::Clear () {
|
||||
void FrameRate::Clear () {
|
||||
Frame.clear();
|
||||
}
|
||||
|
||||
|
||||
////////////////
|
||||
// V2 Add frame
|
||||
void VFR_v2::AddFrame(double fps) {
|
||||
Frame.push_back(fps);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////
|
||||
// V2 Get frame at time
|
||||
int VFR_v2::GetFrameAtTime(int ms) {
|
||||
// Binary search
|
||||
size_t start = 0;
|
||||
size_t end = Frame.size()-1;
|
||||
size_t cur;
|
||||
bool largerEqual;
|
||||
while (start <= end) {
|
||||
cur = (start+end)>>1;
|
||||
largerEqual = floor(Frame[cur]) + 0.5 >= ms;
|
||||
|
||||
// Found
|
||||
if (largerEqual && (cur == 0 || floor(Frame[cur-1]) + 0.5 < ms)) return cur;
|
||||
|
||||
// Not found
|
||||
if (largerEqual) end = cur-1;
|
||||
else start = cur+1;
|
||||
}
|
||||
|
||||
// Couldn't find
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////
|
||||
// V2 Get time at frame
|
||||
int VFR_v2::GetTimeAtFrame(int frame) {
|
||||
if (Frame.size() > (size_t) frame) return floor(Frame.at(frame));
|
||||
return -1;
|
||||
void FrameRate::AddFrame(int ms) {
|
||||
Frame.push_back(ms);
|
||||
}
|
||||
|
||||
|
||||
//////////////////
|
||||
// V2 Get Average
|
||||
double VFR_v2::GetAverage () {
|
||||
void FrameRate::CalcAverage() {
|
||||
double last = 0.0;
|
||||
int frames = 0;
|
||||
for (std::vector<double>::iterator cur=Frame.begin();cur!=Frame.end();cur++) {
|
||||
for (std::vector<int>::iterator cur=Frame.begin();cur!=Frame.end();cur++) {
|
||||
last = *cur;
|
||||
frames++;
|
||||
}
|
||||
return double(frames)*1000.0/last;
|
||||
|
||||
AverageFrameRate = double(frames)*1000.0/last;
|
||||
}
|
||||
|
||||
|
||||
|
@ -213,19 +74,14 @@ double VFR_v2::GetAverage () {
|
|||
///////////////
|
||||
// Constructor
|
||||
FrameRate::FrameRate() {
|
||||
loaded = false;
|
||||
FrameRateType = NONE;
|
||||
AverageFrameRate = 0;
|
||||
vfr = NULL;
|
||||
Unload();
|
||||
}
|
||||
|
||||
|
||||
//////////////
|
||||
// Destructor
|
||||
FrameRate::~FrameRate() {
|
||||
if (vfr) delete vfr;
|
||||
vfr = NULL;
|
||||
loaded = false;
|
||||
Clear();
|
||||
}
|
||||
|
||||
|
||||
|
@ -234,13 +90,33 @@ FrameRate::~FrameRate() {
|
|||
int FrameRate::GetFrameAtTime(int ms) {
|
||||
if (!loaded) return -1;
|
||||
|
||||
ms = MAX(ms,0); //fix me, unsafe for CorrectFrame... for frame 0?
|
||||
|
||||
if (FrameRateType == CFR) {
|
||||
//return int((double(ms)/1000.0) * AverageFrameRate + 0.5);
|
||||
return floor((double(ms)/1000.0) * AverageFrameRate);
|
||||
}
|
||||
else if (FrameRateType == VFR) {
|
||||
if (vfr) return vfr->GetFrameAtTime(ms);
|
||||
else throw _T("VFR error");
|
||||
if (ms < floor(last_time)) {
|
||||
// Binary search
|
||||
size_t start = 0;
|
||||
size_t end = last_frame;
|
||||
size_t cur;
|
||||
bool largerEqual;
|
||||
while (start <= end) {
|
||||
cur = (start+end)>>1;
|
||||
largerEqual = Frame[cur] >= ms;
|
||||
|
||||
// Found
|
||||
if (largerEqual && (cur == 0 || Frame[cur-1] < ms))
|
||||
return cur;
|
||||
|
||||
// Not found
|
||||
if (largerEqual) end = cur-1;
|
||||
else start = cur+1;
|
||||
}
|
||||
} else if (assumefps != 0) {
|
||||
return last_frame + floor((ms-last_time) * assumefps / 1000);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -251,13 +127,15 @@ int FrameRate::GetFrameAtTime(int ms) {
|
|||
int FrameRate::GetTimeAtFrame(int frame) {
|
||||
if (!loaded) return -1;
|
||||
|
||||
wxASSERT(frame >= 0);
|
||||
|
||||
if (FrameRateType == CFR) {
|
||||
//return int(double(frame) / AverageFrameRate * 1000 + 0.5);
|
||||
return floor(double(frame) / AverageFrameRate * 1000);
|
||||
}
|
||||
else if (FrameRateType == VFR) {
|
||||
if (vfr) return vfr->GetTimeAtFrame(frame);
|
||||
else throw _T("VFR error");
|
||||
} 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);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -277,123 +155,112 @@ 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();
|
||||
|
||||
// Read header
|
||||
char buffer[65536];
|
||||
file.getline(buffer,65536);
|
||||
wxString header(buffer,wxConvUTF8);
|
||||
header.LowerCase();
|
||||
header.Trim(true);
|
||||
header.Trim(false);
|
||||
bool forceV1 = false;
|
||||
if (header.Left(17) != _T("# timecode format")) {
|
||||
if (header.Left(6) == _T("assume")) forceV1 = true;
|
||||
else {
|
||||
file.close();
|
||||
throw _T("Unknown file format.");
|
||||
}
|
||||
}
|
||||
|
||||
// V1
|
||||
if (forceV1 || header.Mid(18,2) == _T("v1")) {
|
||||
// Read "assume" line
|
||||
wxString curLine;
|
||||
if (!forceV1) {
|
||||
file.getline(buffer,65536);
|
||||
wxString tmp(buffer,wxConvUTF8);
|
||||
curLine = tmp;
|
||||
}
|
||||
else curLine = header;
|
||||
|
||||
// Process "assume" line
|
||||
curLine.LowerCase();
|
||||
curLine.Trim(true);
|
||||
curLine.Trim(false);
|
||||
if (curLine.Left(6) != _T("assume")) {
|
||||
file.close();
|
||||
throw _T("Error parsing file.");
|
||||
}
|
||||
double temp;
|
||||
curLine.Mid(6).ToDouble(&temp);
|
||||
double assume = GetTrueRate(temp);
|
||||
|
||||
// Assigns new VFR file
|
||||
if (vfr) delete vfr;
|
||||
VFR_v1 *workvfr = new VFR_v1;
|
||||
vfr = workvfr;
|
||||
FrameRateType = VFR;
|
||||
|
||||
// Reads body
|
||||
wxString curline;
|
||||
size_t pos;
|
||||
size_t end;
|
||||
int startf = -1;
|
||||
int endf = -1;
|
||||
double fps;
|
||||
//int n = 0;
|
||||
while (!file.eof()) {
|
||||
file.getline (buffer,65536);
|
||||
wxString wxbuffer (buffer,wxConvUTF8);
|
||||
curline = wxbuffer;
|
||||
if (curline.IsEmpty()) continue;
|
||||
wxString temp;
|
||||
|
||||
// Get start frame
|
||||
pos = 0;
|
||||
end = curline.find(_T(","),pos);
|
||||
//startf = atoi(curline.substr(pos,end-pos).c_str());
|
||||
temp = curline.substr(pos,end-pos);
|
||||
long templ;
|
||||
temp.ToLong(&templ);
|
||||
startf = templ;
|
||||
|
||||
// Fill default's blank
|
||||
if (endf != startf-1) workvfr->AddRange(endf+1,startf-1,assume,true);
|
||||
|
||||
// Get end frame
|
||||
pos = end+1;
|
||||
end = curline.find(_T(","),pos);
|
||||
//endf = atoi(curline.substr(pos,end-pos).c_str());
|
||||
temp = curline.substr(pos,end-pos);
|
||||
temp.ToLong(&templ);
|
||||
endf = templ;
|
||||
|
||||
// Get fps
|
||||
pos = end+1;
|
||||
end = curline.find(_T(","),pos);
|
||||
//fps = atof(curline.substr(pos,end-pos).c_str());
|
||||
temp = curline.substr(pos,end-pos);
|
||||
temp.ToDouble(&fps);
|
||||
fps = GetTrueRate(fps);
|
||||
// V1, code converted from avcvfr9
|
||||
if (header == _T("# timecode format v1")) {
|
||||
//locate the default fps line
|
||||
|
||||
//n++;
|
||||
//wxLogMessage(wxString::Format(_T("Range %i added: %i -> %i at %f fps"),n,startf,endf,fps));
|
||||
workvfr->AddRange(startf,endf,fps,false);
|
||||
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(','));
|
||||
wxString temp = curLine.BeforeFirst(_T(','));
|
||||
temp.ToLong(&lstart);
|
||||
temp = tmp.BeforeLast(_T(','));
|
||||
temp.ToLong(&lend);
|
||||
temp = tmp.AfterLast(_T(','));
|
||||
temp.ToDouble(&lfps);
|
||||
|
||||
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.Mid(18,2) == _T("v2")) {
|
||||
else if (header == _T("# timecode format v2")) {
|
||||
// Assigns new VFR file
|
||||
if (vfr) delete vfr;
|
||||
VFR_v2 *workvfr = new VFR_v2;
|
||||
vfr = workvfr;
|
||||
FrameRateType = VFR;
|
||||
|
||||
long lftime = -1;
|
||||
long cftime = 0;
|
||||
last_frame = 0;
|
||||
|
||||
// Reads body
|
||||
while (!file.eof()) {
|
||||
file.getline (buffer,65536);
|
||||
if (strcmp(buffer,"") == 0) continue;
|
||||
workvfr->AddFrame(atof(buffer));
|
||||
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);
|
||||
wxASSERT(lftime < cftime);
|
||||
AddFrame(cftime);
|
||||
lftime = cftime;
|
||||
}
|
||||
|
||||
// Sorts vector
|
||||
sort(workvfr->Frame.begin(),workvfr->Frame.end());
|
||||
last_time = cftime;
|
||||
last_frame = Frame.size();
|
||||
|
||||
}
|
||||
|
||||
// Unknown
|
||||
else {
|
||||
file.close();
|
||||
throw _T("Unsupported file version.");
|
||||
Unload();
|
||||
throw _T("Unknown file format.");
|
||||
}
|
||||
|
||||
// Run test
|
||||
|
@ -402,9 +269,9 @@ void FrameRate::Load(wxString filename) {
|
|||
int fail = 0;
|
||||
int res;
|
||||
for (int i=0;i<1000;i++) {
|
||||
res = vfr->GetFrameAtTime(vfr->GetTimeAtFrame(i));
|
||||
res = GetFrameAtTime(GetTimeAtFrame(i));
|
||||
if (res != i) {
|
||||
wxLogMessage(wxString::Format(_T("Expected %i but got %i (%i)"),i,res,vfr->GetTimeAtFrame(i)));
|
||||
wxLogMessage(wxString::Format(_T("Expected %i but got %i (%i)"),i,res,GetTimeAtFrame(i)));
|
||||
fail++;
|
||||
}
|
||||
}
|
||||
|
@ -416,7 +283,8 @@ void FrameRate::Load(wxString filename) {
|
|||
file.close();
|
||||
loaded = true;
|
||||
vfrFile = filename;
|
||||
AverageFrameRate = vfr->GetAverage();
|
||||
FrameRateType = VFR;
|
||||
CalcAverage();
|
||||
}
|
||||
|
||||
|
||||
|
@ -425,8 +293,10 @@ void FrameRate::Load(wxString filename) {
|
|||
void FrameRate::Unload () {
|
||||
FrameRateType = NONE;
|
||||
AverageFrameRate = 0;
|
||||
if (vfr) delete vfr;
|
||||
vfr = NULL;
|
||||
assumefps = 0;
|
||||
last_time = 0;
|
||||
last_frame = 0;
|
||||
Clear();
|
||||
loaded = false;
|
||||
vfrFile = _T("");
|
||||
}
|
||||
|
@ -437,30 +307,17 @@ void FrameRate::Unload () {
|
|||
void FrameRate::SetCFR(double fps,bool ifunset) {
|
||||
if (loaded && ifunset) return;
|
||||
|
||||
if (vfr) delete vfr;
|
||||
vfr = NULL;
|
||||
Unload();
|
||||
loaded = true;
|
||||
vfrFile = _T("");
|
||||
FrameRateType = CFR;
|
||||
AverageFrameRate = fps;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////
|
||||
// Improve precision of fps
|
||||
double FrameRate::GetTrueRate(double rate) {
|
||||
//if (rate == 23.976) {
|
||||
// rate = 24.0 / 1.001;
|
||||
//}
|
||||
//if (rate == 29.97) {
|
||||
// rate = 30.0 / 1.001;
|
||||
//}
|
||||
return rate;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// 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;
|
||||
|
||||
|
@ -476,10 +333,8 @@ int FrameRate::CorrectFrameAtTime(int ms,bool start) {
|
|||
|
||||
// VFR
|
||||
else {
|
||||
int delta = 0;
|
||||
if (!start) delta = -1;
|
||||
//frame = GetFrameAtTime(ms-delta)+delta;
|
||||
frame = GetFrameAtTime(ms)+delta;
|
||||
frame = GetFrameAtTime(ms);
|
||||
if (!start) frame--;
|
||||
}
|
||||
|
||||
return frame;
|
||||
|
@ -488,16 +343,12 @@ int FrameRate::CorrectFrameAtTime(int ms,bool start) {
|
|||
|
||||
/////////////////////////////
|
||||
// Get correct time at frame
|
||||
// compensates and returns an end time when start=false
|
||||
int FrameRate::CorrectTimeAtFrame(int frame,bool start) {
|
||||
//int startDelta = 0;
|
||||
//if (start) startDelta = -1;
|
||||
//int delta = 1;
|
||||
//if (FrameRateType == VFR) delta = 1;
|
||||
//return GetTimeAtFrame(frame+delta+startDelta)+startDelta;
|
||||
|
||||
int delta = 0;
|
||||
if (!start) delta = 1;
|
||||
return GetTimeAtFrame(frame+delta);
|
||||
if (start)
|
||||
return GetTimeAtFrame(frame);
|
||||
else
|
||||
return GetTimeAtFrame(frame+1);
|
||||
}
|
||||
|
||||
|
||||
|
|
76
core/vfr.h
76
core/vfr.h
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2005, Rodrigo Braz Monteiro
|
||||
// Copyright (c) 2005-2006, Rodrigo Braz Monteiro, Fredrik Mellbin
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
|
@ -33,6 +33,10 @@
|
|||
// Contact: mailto:zeratul@cellosoft.com
|
||||
//
|
||||
|
||||
// The FrameRate class stores all times internally as ints in ms precision
|
||||
// V1 timecodes are partially expanded to v2 up until their last override line
|
||||
// V2 timecodes are kept as is and if n frames beyond the end is requested a
|
||||
// time is calculated by last_time+n/average_fps
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -52,71 +56,28 @@ enum ASS_FrameRateType {
|
|||
VFR
|
||||
};
|
||||
|
||||
|
||||
///////////////////////
|
||||
// Base abstract class
|
||||
class VFR_Base {
|
||||
public:
|
||||
virtual int GetFrameAtTime(int ms)=0;
|
||||
virtual int GetTimeAtFrame(int frame)=0;
|
||||
virtual double GetAverage()=0;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////
|
||||
// V1 Timecodes Classes
|
||||
class VFR_v1_Range {
|
||||
public:
|
||||
bool isDefault;
|
||||
int start;
|
||||
int end;
|
||||
double fps;
|
||||
};
|
||||
|
||||
class VFR_v1 : public VFR_Base {
|
||||
private:
|
||||
std::list<VFR_v1_Range> Range;
|
||||
double DefaultFPS;
|
||||
|
||||
public:
|
||||
VFR_v1();
|
||||
~VFR_v1();
|
||||
void Clear();
|
||||
void AddRange(int start,int end,double fps,bool isdefault);
|
||||
int GetFrameAtTime(int ms);
|
||||
int GetTimeAtFrame(int frame);
|
||||
double GetAverage();
|
||||
};
|
||||
|
||||
|
||||
//////////////////////
|
||||
// V2 Timecodes Class
|
||||
class VFR_v2 : public VFR_Base {
|
||||
public:
|
||||
std::vector<double> Frame;
|
||||
|
||||
VFR_v2();
|
||||
~VFR_v2();
|
||||
void Clear();
|
||||
void AddFrame(double fps);
|
||||
int GetFrameAtTime(int ms);
|
||||
int GetTimeAtFrame(int frame);
|
||||
double GetAverage();
|
||||
};
|
||||
|
||||
|
||||
///////////////////
|
||||
// Framerate class
|
||||
class FrameRate {
|
||||
private:
|
||||
double last_time;
|
||||
int last_frame;
|
||||
std::vector<int> Frame;
|
||||
double assumefps;
|
||||
double AverageFrameRate;
|
||||
|
||||
void AddFrame(int ms);
|
||||
void Clear();
|
||||
|
||||
void CalcAverage();
|
||||
public:
|
||||
FrameRate();
|
||||
~FrameRate();
|
||||
|
||||
|
||||
wxString vfrFile;
|
||||
bool loaded;
|
||||
ASS_FrameRateType FrameRateType;
|
||||
double AverageFrameRate;
|
||||
VFR_Base *vfr;
|
||||
|
||||
void SetCFR(double fps,bool ifunset=false);
|
||||
void Load(wxString file);
|
||||
|
@ -125,7 +86,8 @@ public:
|
|||
int GetTimeAtFrame(int frame);
|
||||
int CorrectFrameAtTime(int ms,bool start);
|
||||
int CorrectTimeAtFrame(int frame,bool start);
|
||||
double GetTrueRate(double fps);
|
||||
|
||||
double GetAverage() { return AverageFrameRate; };
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -138,7 +138,7 @@ void VideoDisplay::SetVideo(const wxString &filename) {
|
|||
if (filename.IsEmpty()) {
|
||||
delete provider;
|
||||
provider = NULL;
|
||||
if (VFR_Output.vfr == NULL) VFR_Output.Unload();
|
||||
if (VFR_Output.FrameRateType == VFR) VFR_Output.Unload();
|
||||
VFR_Input.Unload();
|
||||
|
||||
videoName = _T("");
|
||||
|
|
Loading…
Reference in a new issue