forked from mia/Aegisub
Use agi::vfr::Framerate in FractionalTime rather than a numerator\denominator pair
Originally committed to SVN as r6119.
This commit is contained in:
parent
ab68b4b080
commit
a91f6f7880
6 changed files with 33 additions and 55 deletions
|
@ -251,20 +251,10 @@ int AssTime::GetTimeMiliseconds() { return (time % 1000); }
|
||||||
///
|
///
|
||||||
int AssTime::GetTimeCentiseconds() { return (time % 1000)/10; }
|
int AssTime::GetTimeCentiseconds() { return (time % 1000)/10; }
|
||||||
|
|
||||||
FractionalTime::FractionalTime(int numerator, int denominator, bool dropframe)
|
FractionalTime::FractionalTime(agi::vfr::Framerate fps, bool dropframe)
|
||||||
: num(numerator)
|
: fps(fps)
|
||||||
, den(denominator)
|
|
||||||
, drop(dropframe)
|
, 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) {
|
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) {
|
wxString FractionalTime::FromMillisecs(int64_t msec, char sep) {
|
||||||
int h=0, m=0, s=0, f=0; // hours, minutes, seconds, fractions
|
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
|
// return 00:00:00:00
|
||||||
if (msec <= 0) {
|
if (msec <= 0) {
|
||||||
|
@ -302,7 +292,7 @@ wxString FractionalTime::FromMillisecs(int64_t msec, char sep) {
|
||||||
|
|
||||||
DEATH TO SMPTE
|
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_h = 3600*fps_approx;
|
||||||
int frames_per_m = 60*fps_approx;
|
int frames_per_m = 60*fps_approx;
|
||||||
int frames_per_s = fps_approx;
|
int frames_per_s = fps_approx;
|
||||||
|
|
|
@ -42,6 +42,8 @@
|
||||||
#include <wx/string.h>
|
#include <wx/string.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <libaegisub/vfr.h>
|
||||||
|
|
||||||
/// DOCME
|
/// DOCME
|
||||||
/// @class AssTime
|
/// @class AssTime
|
||||||
/// @brief DOCME
|
/// @brief DOCME
|
||||||
|
@ -87,20 +89,17 @@ AssTime operator - (const AssTime &t1, const AssTime &t2);
|
||||||
///
|
///
|
||||||
/// DOCME
|
/// DOCME
|
||||||
class FractionalTime {
|
class FractionalTime {
|
||||||
int time; ///< Time in miliseconds
|
agi::vfr::Framerate fps;
|
||||||
int num; ///< Numerator
|
|
||||||
int den; ///< Denominator
|
|
||||||
bool drop; ///< Enable SMPTE dropframe handling
|
bool drop; ///< Enable SMPTE dropframe handling
|
||||||
|
|
||||||
/// How often to drop frames when enabled
|
/// How often to drop frames when enabled
|
||||||
static const int frames_per_period = 17982;
|
static const int frames_per_period = 17982;
|
||||||
|
|
||||||
public:
|
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; }
|
bool IsDrop() const { return drop; }
|
||||||
|
agi::vfr::Framerate const& FPS() const { return fps; }
|
||||||
|
|
||||||
/// Convert an AssTime to a SMPTE timecode
|
/// Convert an AssTime to a SMPTE timecode
|
||||||
wxString FromAssTime(AssTime time, char sep=':');
|
wxString FromAssTime(AssTime time, char sep=':');
|
||||||
|
|
|
@ -112,8 +112,6 @@ void SubtitleFormat::AddLine(wxString data, wxString group, int &version, wxStri
|
||||||
FractionalTime SubtitleFormat::AskForFPS(bool showSMPTE) {
|
FractionalTime SubtitleFormat::AskForFPS(bool showSMPTE) {
|
||||||
wxArrayString choices;
|
wxArrayString choices;
|
||||||
bool drop = false;
|
bool drop = false;
|
||||||
int num;
|
|
||||||
int den;
|
|
||||||
|
|
||||||
// Video FPS
|
// Video FPS
|
||||||
VideoContext *context = VideoContext::Get();
|
VideoContext *context = VideoContext::Get();
|
||||||
|
@ -142,10 +140,12 @@ FractionalTime SubtitleFormat::AskForFPS(bool showSMPTE) {
|
||||||
choices.Add(_("119.880 FPS (NTSC x4)"));
|
choices.Add(_("119.880 FPS (NTSC x4)"));
|
||||||
choices.Add(_("120.000 FPS"));
|
choices.Add(_("120.000 FPS"));
|
||||||
|
|
||||||
|
using agi::vfr::Framerate;
|
||||||
|
Framerate fps;
|
||||||
// Ask
|
// Ask
|
||||||
int choice = wxGetSingleChoiceIndex(_("Please choose the appropriate FPS for the subtitles:"), _("FPS"), choices);
|
int choice = wxGetSingleChoiceIndex(_("Please choose the appropriate FPS for the subtitles:"), _("FPS"), choices);
|
||||||
if (choice == -1)
|
if (choice == -1)
|
||||||
return FractionalTime(0, 0);
|
return FractionalTime(fps);
|
||||||
|
|
||||||
// Get FPS from choice
|
// Get FPS from choice
|
||||||
if (vidLoaded) choice--;
|
if (vidLoaded) choice--;
|
||||||
|
@ -153,22 +153,22 @@ FractionalTime SubtitleFormat::AskForFPS(bool showSMPTE) {
|
||||||
if (!showSMPTE && choice > 4) ++choice;
|
if (!showSMPTE && choice > 4) ++choice;
|
||||||
|
|
||||||
switch (choice) {
|
switch (choice) {
|
||||||
case -1: num = -1; den = 1; break; // VIDEO
|
case -1: fps = context->FPS(); break; // VIDEO
|
||||||
case 0: num = 15; den = 1; break;
|
case 0: fps = Framerate(15, 1); break;
|
||||||
case 1: num = 24000; den = 1001; break;
|
case 1: fps = Framerate(24000, 1001); break;
|
||||||
case 2: num = 24; den = 1; break;
|
case 2: fps = Framerate(24, 1); break;
|
||||||
case 3: num = 25; den = 1; break;
|
case 3: fps = Framerate(25, 1); break;
|
||||||
case 4: num = 30000; den = 1001; break;
|
case 4: fps = Framerate(30000, 1001); break;
|
||||||
case 5: num = 30000; den = 1001; drop = true; break;
|
case 5: fps = Framerate(30000, 1001); drop = true; break;
|
||||||
case 6: num = 30; den = 1; break;
|
case 6: fps = Framerate(30, 1); break;
|
||||||
case 7: num = 50; den = 1; break;
|
case 7: fps = Framerate(50, 1); break;
|
||||||
case 8: num = 60000; den = 1001; break;
|
case 8: fps = Framerate(60000, 1001); break;
|
||||||
case 9: num = 60; den = 1; break;
|
case 9: fps = Framerate(60, 1); break;
|
||||||
case 10: num = 120000; den = 1001; break;
|
case 10: fps = Framerate(120000, 1001); break;
|
||||||
case 11: num = 120; den = 1; break;
|
case 11: fps = Framerate(120, 1); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return FractionalTime(num, den, drop);
|
return FractionalTime(fps, drop);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SubtitleFormat::SortLines() {
|
void SubtitleFormat::SortLines() {
|
||||||
|
|
|
@ -54,7 +54,7 @@ wxArrayString EncoreSubtitleFormat::GetWriteWildcards() const {
|
||||||
|
|
||||||
void EncoreSubtitleFormat::WriteFile(wxString const& filename, wxString const& encoding) {
|
void EncoreSubtitleFormat::WriteFile(wxString const& filename, wxString const& encoding) {
|
||||||
FractionalTime ft = AskForFPS(true);
|
FractionalTime ft = AskForFPS(true);
|
||||||
if (ft.Numerator() <= 0 || ft.Denominator() <= 0) return;
|
if (!ft.FPS().IsLoaded()) return;
|
||||||
|
|
||||||
TextFileWriter file(filename, encoding);
|
TextFileWriter file(filename, encoding);
|
||||||
|
|
||||||
|
|
|
@ -107,12 +107,8 @@ void MicroDVDSubtitleFormat::ReadFile(wxString const& filename, wxString const&
|
||||||
}
|
}
|
||||||
|
|
||||||
// If it wasn't an fps line, ask the user for it
|
// If it wasn't an fps line, ask the user for it
|
||||||
FractionalTime fps_rat = AskForFPS();
|
fps = AskForFPS().FPS();
|
||||||
if (fps_rat.Numerator() == 0) return;
|
if (!fps.IsLoaded()) return;
|
||||||
else if (fps_rat.Numerator() > 0)
|
|
||||||
fps = agi::vfr::Framerate(fps_rat.Numerator(), fps_rat.Denominator());
|
|
||||||
else
|
|
||||||
fps = VideoContext::Get()->FPS();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
text.Replace("|", "\\N");
|
text.Replace("|", "\\N");
|
||||||
|
@ -129,16 +125,9 @@ void MicroDVDSubtitleFormat::ReadFile(wxString const& filename, wxString const&
|
||||||
}
|
}
|
||||||
|
|
||||||
void MicroDVDSubtitleFormat::WriteFile(wxString const& filename, wxString const& encoding) {
|
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();
|
CreateCopy();
|
||||||
SortLines();
|
SortLines();
|
||||||
StripComments();
|
StripComments();
|
||||||
|
|
|
@ -61,7 +61,7 @@ wxArrayString TranStationSubtitleFormat::GetWriteWildcards() const {
|
||||||
|
|
||||||
void TranStationSubtitleFormat::WriteFile(wxString const& filename, wxString const& encoding) {
|
void TranStationSubtitleFormat::WriteFile(wxString const& filename, wxString const& encoding) {
|
||||||
FractionalTime ft = AskForFPS(true);
|
FractionalTime ft = AskForFPS(true);
|
||||||
if (ft.Numerator() <= 0 || ft.Denominator() <= 0) return;
|
if (!ft.FPS().IsLoaded()) return;
|
||||||
|
|
||||||
TextFileWriter file(filename, encoding);
|
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
|
// start of next one, since the end timestamp is inclusive and the lines
|
||||||
// would overlap if left as is.
|
// would overlap if left as is.
|
||||||
if (nextl_start > 0 && end.GetMS() == nextl_start)
|
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";
|
wxString header = wxString::Format("SUB[%i%s%s ", valign, halign, type) + ft->FromAssTime(start) + ">" + ft->FromAssTime(end) + "]\r\n";
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue