Use agi::vfr::Framerate in FractionalTime rather than a numerator\denominator pair

Originally committed to SVN as r6119.
This commit is contained in:
Thomas Goyne 2011-12-22 21:28:13 +00:00
parent ab68b4b080
commit a91f6f7880
6 changed files with 33 additions and 55 deletions

View File

@ -251,20 +251,10 @@ int AssTime::GetTimeMiliseconds() { return (time % 1000); }
///
int AssTime::GetTimeCentiseconds() { return (time % 1000)/10; }
FractionalTime::FractionalTime(int numerator, int denominator, bool dropframe)
: num(numerator)
, den(denominator)
FractionalTime::FractionalTime(agi::vfr::Framerate fps, bool dropframe)
: fps(fps)
, drop(dropframe)
{
if (drop) {
// no dropframe for any other framerates
num = 30000;
den = 1001;
}
// fractions < 1 are not welcome here
if ((num <= 0 || den <= 0) || (num < den))
throw "FractionalTime: nonsensical enumerator or denominator";
}
wxString FractionalTime::FromAssTime(AssTime time, char sep) {
@ -273,7 +263,7 @@ wxString FractionalTime::FromAssTime(AssTime time, char sep) {
wxString FractionalTime::FromMillisecs(int64_t msec, char sep) {
int h=0, m=0, s=0, f=0; // hours, minutes, seconds, fractions
int fn = (msec*(int64_t)num) / (1000*den); // frame number
int fn = fps.FrameAtTime(msec);
// return 00:00:00:00
if (msec <= 0) {
@ -302,7 +292,7 @@ wxString FractionalTime::FromMillisecs(int64_t msec, char sep) {
DEATH TO SMPTE
*/
int fps_approx = floor((double(num)/double(den))+0.5);
int fps_approx = floor(fps.FPS() + 0.5);
int frames_per_h = 3600*fps_approx;
int frames_per_m = 60*fps_approx;
int frames_per_s = fps_approx;

View File

@ -42,6 +42,8 @@
#include <wx/string.h>
#endif
#include <libaegisub/vfr.h>
/// DOCME
/// @class AssTime
/// @brief DOCME
@ -87,20 +89,17 @@ AssTime operator - (const AssTime &t1, const AssTime &t2);
///
/// DOCME
class FractionalTime {
int time; ///< Time in miliseconds
int num; ///< Numerator
int den; ///< Denominator
agi::vfr::Framerate fps;
bool drop; ///< Enable SMPTE dropframe handling
/// How often to drop frames when enabled
static const int frames_per_period = 17982;
public:
FractionalTime(int numerator=30, int denominator=1, bool dropframe=false);
FractionalTime(agi::vfr::Framerate fps, bool dropframe = false);
int Numerator() const { return num; }
int Denominator() const { return den; }
bool IsDrop() const { return drop; }
agi::vfr::Framerate const& FPS() const { return fps; }
/// Convert an AssTime to a SMPTE timecode
wxString FromAssTime(AssTime time, char sep=':');

View File

@ -112,8 +112,6 @@ void SubtitleFormat::AddLine(wxString data, wxString group, int &version, wxStri
FractionalTime SubtitleFormat::AskForFPS(bool showSMPTE) {
wxArrayString choices;
bool drop = false;
int num;
int den;
// Video FPS
VideoContext *context = VideoContext::Get();
@ -142,10 +140,12 @@ FractionalTime SubtitleFormat::AskForFPS(bool showSMPTE) {
choices.Add(_("119.880 FPS (NTSC x4)"));
choices.Add(_("120.000 FPS"));
using agi::vfr::Framerate;
Framerate fps;
// Ask
int choice = wxGetSingleChoiceIndex(_("Please choose the appropriate FPS for the subtitles:"), _("FPS"), choices);
if (choice == -1)
return FractionalTime(0, 0);
return FractionalTime(fps);
// Get FPS from choice
if (vidLoaded) choice--;
@ -153,22 +153,22 @@ FractionalTime SubtitleFormat::AskForFPS(bool showSMPTE) {
if (!showSMPTE && choice > 4) ++choice;
switch (choice) {
case -1: num = -1; den = 1; break; // VIDEO
case 0: num = 15; den = 1; break;
case 1: num = 24000; den = 1001; break;
case 2: num = 24; den = 1; break;
case 3: num = 25; den = 1; break;
case 4: num = 30000; den = 1001; break;
case 5: num = 30000; den = 1001; drop = true; break;
case 6: num = 30; den = 1; break;
case 7: num = 50; den = 1; break;
case 8: num = 60000; den = 1001; break;
case 9: num = 60; den = 1; break;
case 10: num = 120000; den = 1001; break;
case 11: num = 120; den = 1; break;
case -1: fps = context->FPS(); break; // VIDEO
case 0: fps = Framerate(15, 1); break;
case 1: fps = Framerate(24000, 1001); break;
case 2: fps = Framerate(24, 1); break;
case 3: fps = Framerate(25, 1); break;
case 4: fps = Framerate(30000, 1001); break;
case 5: fps = Framerate(30000, 1001); drop = true; break;
case 6: fps = Framerate(30, 1); break;
case 7: fps = Framerate(50, 1); break;
case 8: fps = Framerate(60000, 1001); break;
case 9: fps = Framerate(60, 1); break;
case 10: fps = Framerate(120000, 1001); break;
case 11: fps = Framerate(120, 1); break;
}
return FractionalTime(num, den, drop);
return FractionalTime(fps, drop);
}
void SubtitleFormat::SortLines() {

View File

@ -54,7 +54,7 @@ wxArrayString EncoreSubtitleFormat::GetWriteWildcards() const {
void EncoreSubtitleFormat::WriteFile(wxString const& filename, wxString const& encoding) {
FractionalTime ft = AskForFPS(true);
if (ft.Numerator() <= 0 || ft.Denominator() <= 0) return;
if (!ft.FPS().IsLoaded()) return;
TextFileWriter file(filename, encoding);

View File

@ -107,12 +107,8 @@ void MicroDVDSubtitleFormat::ReadFile(wxString const& filename, wxString const&
}
// If it wasn't an fps line, ask the user for it
FractionalTime fps_rat = AskForFPS();
if (fps_rat.Numerator() == 0) return;
else if (fps_rat.Numerator() > 0)
fps = agi::vfr::Framerate(fps_rat.Numerator(), fps_rat.Denominator());
else
fps = VideoContext::Get()->FPS();
fps = AskForFPS().FPS();
if (!fps.IsLoaded()) return;
}
text.Replace("|", "\\N");
@ -129,16 +125,9 @@ void MicroDVDSubtitleFormat::ReadFile(wxString const& filename, wxString const&
}
void MicroDVDSubtitleFormat::WriteFile(wxString const& filename, wxString const& encoding) {
agi::vfr::Framerate fps;
agi::vfr::Framerate fps = AskForFPS().FPS();
if (!fps.IsLoaded()) return;
FractionalTime fps_rat = AskForFPS();
if (fps_rat.Numerator() == 0 || fps_rat.Denominator() == 0) return;
if (fps_rat.Numerator() < 0 || fps_rat.Denominator() < 0)
fps = VideoContext::Get()->FPS();
else
fps = agi::vfr::Framerate(fps_rat.Numerator(), fps_rat.Denominator());
// Convert file
CreateCopy();
SortLines();
StripComments();

View File

@ -61,7 +61,7 @@ wxArrayString TranStationSubtitleFormat::GetWriteWildcards() const {
void TranStationSubtitleFormat::WriteFile(wxString const& filename, wxString const& encoding) {
FractionalTime ft = AskForFPS(true);
if (ft.Numerator() <= 0 || ft.Denominator() <= 0) return;
if (!ft.FPS().IsLoaded()) return;
TextFileWriter file(filename, encoding);
@ -119,7 +119,7 @@ wxString TranStationSubtitleFormat::ConvertLine(AssDialogue *current, Fractional
// start of next one, since the end timestamp is inclusive and the lines
// would overlap if left as is.
if (nextl_start > 0 && end.GetMS() == nextl_start)
end.SetMS(end.GetMS() - ((1000*ft->Denominator())/ft->Numerator()));
end.SetMS(ft->FPS().TimeAtFrame(ft->FPS().FrameAtTime(end.GetMS(), agi::vfr::END) - 1, agi::vfr::END));
wxString header = wxString::Format("SUB[%i%s%s ", valign, halign, type) + ft->FromAssTime(start) + ">" + ft->FromAssTime(end) + "]\r\n";