diff --git a/aegisub/build/aegisub_vs2008/aegisub_vs2008.vcproj b/aegisub/build/aegisub_vs2008/aegisub_vs2008.vcproj
index 1af3f70ee..58346ac66 100644
--- a/aegisub/build/aegisub_vs2008/aegisub_vs2008.vcproj
+++ b/aegisub/build/aegisub_vs2008/aegisub_vs2008.vcproj
@@ -1011,14 +1011,6 @@
RelativePath="..\..\src\vector2d.h"
>
-
-
-
-
const& timecodes)
: timecodes(timecodes)
{
validate_timecodes(timecodes);
- fps = timecodes.size() / (timecodes.back() / 1000.);
+ fps = (timecodes.size() - 1) * 1000. / (timecodes.back() - timecodes.front());
last = timecodes.back();
}
@@ -202,10 +202,6 @@ Framerate &Framerate::operator=(double fps) {
return *this = Framerate(fps);
}
-bool Framerate::operator==(Framerate const& right) const {
- return fps == right.fps && timecodes == right.timecodes;
-}
-
Framerate::Framerate(std::string const& filename) : fps(0.) {
using namespace std;
auto_ptr file(agi::io::Open(filename));
@@ -214,7 +210,8 @@ Framerate::Framerate(std::string const& filename) : fps(0.) {
if (line == "# timecode format v2") {
copy(line_iterator(*file, encoding), line_iterator(), back_inserter(timecodes));
validate_timecodes(timecodes);
- fps = timecodes.size() / (timecodes.back() / 1000.);
+ fps = (timecodes.size() - 1) * 1000. / (timecodes.back() - timecodes.front());
+ last = timecodes.back();
return;
}
if (line == "# timecode format v1" || line.substr(0, 7) == "Assume ") {
diff --git a/aegisub/libaegisub/include/libaegisub/vfr.h b/aegisub/libaegisub/include/libaegisub/vfr.h
index 046010b86..2aff1d1e5 100644
--- a/aegisub/libaegisub/include/libaegisub/vfr.h
+++ b/aegisub/libaegisub/include/libaegisub/vfr.h
@@ -132,10 +132,6 @@ public:
bool IsVFR() const {return !timecodes.empty(); }
bool IsLoaded() const { return !timecodes.empty() || fps; };
double FPS() const { return fps; }
-
- /// @brief Equality operator
- /// @attention O(n) when both arguments are VFR
- bool operator==(Framerate const& right) const;
};
}
diff --git a/aegisub/src/Makefile.am b/aegisub/src/Makefile.am
index 9e87b6604..ba4c19e9c 100644
--- a/aegisub/src/Makefile.am
+++ b/aegisub/src/Makefile.am
@@ -302,7 +302,6 @@ aegisub_2_2_SOURCES = \
variable_data.cpp \
vector2d.cpp \
version.cpp \
- vfr.cpp \
video_box.cpp \
video_context.cpp \
video_display.cpp \
diff --git a/aegisub/src/ass_dialogue.cpp b/aegisub/src/ass_dialogue.cpp
index ce848710d..6574bdc86 100644
--- a/aegisub/src/ass_dialogue.cpp
+++ b/aegisub/src/ass_dialogue.cpp
@@ -45,7 +45,6 @@
#include "ass_dialogue.h"
#include "ass_override.h"
#include "utils.h"
-#include "vfr.h"
AssDialogue::AssDialogue()
: Comment(false)
diff --git a/aegisub/src/ass_file.cpp b/aegisub/src/ass_file.cpp
index 7ab0cae88..b52b17176 100644
--- a/aegisub/src/ass_file.cpp
+++ b/aegisub/src/ass_file.cpp
@@ -60,7 +60,6 @@
#include "text_file_writer.h"
#include "utils.h"
#include "version.h"
-#include "vfr.h"
/// @brief AssFile constructor
AssFile::AssFile () {
diff --git a/aegisub/src/ass_time.cpp b/aegisub/src/ass_time.cpp
index 23fdf9b95..5d7631ddb 100644
--- a/aegisub/src/ass_time.cpp
+++ b/aegisub/src/ass_time.cpp
@@ -50,7 +50,6 @@
#include "ass_time.h"
#include "utils.h"
-#include "vfr.h"
/// @brief AssTime constructors
diff --git a/aegisub/src/audio_display.cpp b/aegisub/src/audio_display.cpp
index 32c95061d..6c76f1ab2 100644
--- a/aegisub/src/audio_display.cpp
+++ b/aegisub/src/audio_display.cpp
@@ -65,7 +65,6 @@
#include "subs_grid.h"
#include "timeedit_ctrl.h"
#include "utils.h"
-#include "vfr.h"
#include "video_context.h"
#ifdef __WXMAC__
@@ -295,7 +294,7 @@ void AudioDisplay::DoUpdateImage() {
if (OPT_GET("Audio/Display/Draw/Video Position")->GetBool()) {
if (VideoContext::Get()->IsLoaded()) {
dc.SetPen(wxPen(lagi_wxColour(OPT_GET("Colour/Audio Display/Play Cursor")->GetColour())));
- int x = GetXAtMS(VFR_Output.GetTimeAtFrame(VideoContext::Get()->GetFrameN()));
+ int x = GetXAtMS(VideoContext::Get()->TimeAtFrame(VideoContext::Get()->GetFrameN()));
dc.DrawLine(x,0,x,h);
}
}
@@ -477,19 +476,19 @@ void AudioDisplay::DrawInactiveLines(wxDC &dc) {
/// @brief Draw keyframe markers
/// @param dc The DC to draw to.
void AudioDisplay::DrawKeyframes(wxDC &dc) {
- wxArrayInt KeyFrames = VideoContext::Get()->GetKeyFrames();
- int nKeys = (int)KeyFrames.Count();
+ std::vector KeyFrames = VideoContext::Get()->GetKeyFrames();
+ int nKeys = (int)KeyFrames.size();
dc.SetPen(wxPen(wxColour(255,0,255),1));
// Get min and max frames to care about
- int minFrame = VFR_Output.GetFrameAtTime(GetMSAtX(0),true);
- int maxFrame = VFR_Output.GetFrameAtTime(GetMSAtX(w),true);
+ int minFrame = VideoContext::Get()->FrameAtTime(GetMSAtX(0),agi::vfr::START);
+ int maxFrame = VideoContext::Get()->FrameAtTime(GetMSAtX(w),agi::vfr::END);
// Scan list
for (int i=0;i= minFrame && cur <= maxFrame) {
- int x = GetXAtMS(VFR_Output.GetTimeAtFrame(cur,true));
+ int x = GetXAtMS(VideoContext::Get()->TimeAtFrame(cur,agi::vfr::START));
dc.DrawLine(x,0,x,h);
}
else if (cur > maxFrame) break;
@@ -1469,7 +1468,7 @@ void AudioDisplay::OnMouseEvent(wxMouseEvent& event) {
if (middleClick) {
SetFocus();
if (VideoContext::Get()->IsLoaded()) {
- VideoContext::Get()->JumpToTime(GetMSAtX(x),true);
+ VideoContext::Get()->JumpToTime(GetMSAtX(x));
}
}
@@ -1719,13 +1718,13 @@ int AudioDisplay::GetBoundarySnap(int ms,int rangeX,bool shiftHeld,bool start) {
if (shiftHeld) snapKey = !snapKey;
if (snapKey && VideoContext::Get()->KeyFramesLoaded() && OPT_GET("Audio/Display/Draw/Keyframes")->GetBool()) {
int64_t keyMS;
- wxArrayInt keyFrames = VideoContext::Get()->GetKeyFrames();
+ std::vector keyFrames = VideoContext::Get()->GetKeyFrames();
int frame;
- for (unsigned int i=0;iTimeAtFrame(frame,start ? agi::vfr::START : agi::vfr::END);
//if (start) keyX++;
if (GetXAtMS(keyMS) >= 0 && GetXAtMS(keyMS) < w) boundaries.Add(keyMS);
}
diff --git a/aegisub/src/audio_display.h b/aegisub/src/audio_display.h
index ab51d078e..9ea9c630d 100644
--- a/aegisub/src/audio_display.h
+++ b/aegisub/src/audio_display.h
@@ -34,12 +34,8 @@
/// @ingroup audio_ui
///
-
#pragma once
-
-///////////
-// Headers
#ifndef AGI_PRE
#include
@@ -52,9 +48,6 @@
#include "audio_provider_manager.h"
#include "audio_renderer_spectrum.h"
-
-//////////////
-// Prototypes
class AssDialogue;
class StreamAudioProvider;
class SubtitlesGrid;
@@ -63,8 +56,6 @@ class AudioKaraoke;
class VideoProvider;
class FrameMain;
-
-
/// DOCME
/// @class AudioDisplay
/// @brief DOCME
@@ -83,11 +74,9 @@ private:
/// DOCME
AssDialogue *dialogue;
-
/// DOCME
AudioSpectrum *spectrumRenderer;
-
/// DOCME
wxBitmap *origImage;
@@ -127,14 +116,12 @@ private:
/// DOCME
bool playingToEnd;
-
/// DOCME
bool needImageUpdate;
/// DOCME
bool needImageUpdateWeak;
-
/// DOCME
bool hasSel;
@@ -186,14 +173,12 @@ private:
/// DOCME
int holdSyl;
-
/// DOCME
int *peak;
/// DOCME
int *min;
-
/// DOCME
int scrubTime;
@@ -239,7 +224,6 @@ public:
/// DOCME
AudioPlayer *player;
-
/// DOCME
bool NeedCommit;
@@ -308,11 +292,8 @@ public:
DECLARE_EVENT_TABLE()
};
-
///////
// IDs
enum {
-
- /// DOCME
Audio_Update_Timer = 1700
};
diff --git a/aegisub/src/auto4_lua.cpp b/aegisub/src/auto4_lua.cpp
index f77dc4c7e..85b8c280a 100644
--- a/aegisub/src/auto4_lua.cpp
+++ b/aegisub/src/auto4_lua.cpp
@@ -64,7 +64,6 @@
#include "options.h"
#include "standard_paths.h"
#include "text_file_reader.h"
-#include "vfr.h"
#include "video_context.h"
// This must be below the headers above.
@@ -504,8 +503,8 @@ namespace Automation4 {
{
int ms = (int)lua_tonumber(L, -1);
lua_pop(L, 1);
- if (VFR_Output.IsLoaded()) {
- lua_pushnumber(L, VFR_Output.GetFrameAtTime(ms, true));
+ if (VideoContext::Get()->TimecodesLoaded()) {
+ lua_pushnumber(L, VideoContext::Get()->FrameAtTime(ms, agi::vfr::START));
return 1;
} else {
lua_pushnil(L);
@@ -522,8 +521,8 @@ namespace Automation4 {
{
int frame = (int)lua_tonumber(L, -1);
lua_pop(L, 1);
- if (VFR_Output.IsLoaded()) {
- lua_pushnumber(L, VFR_Output.GetTimeAtFrame(frame, true));
+ if (VideoContext::Get()->TimecodesLoaded()) {
+ lua_pushnumber(L, VideoContext::Get()->TimeAtFrame(frame, agi::vfr::START));
return 1;
} else {
lua_pushnil(L);
diff --git a/aegisub/src/auto4_lua.h b/aegisub/src/auto4_lua.h
index 72bd71a0f..e1c2e9c37 100644
--- a/aegisub/src/auto4_lua.h
+++ b/aegisub/src/auto4_lua.h
@@ -53,6 +53,7 @@
#endif
class wxWindow;
+namespace agi { namespace vfr { class Framerate; } }
/// DOCME
diff --git a/aegisub/src/base_grid.cpp b/aegisub/src/base_grid.cpp
index 600f5cc67..5527e512b 100644
--- a/aegisub/src/base_grid.cpp
+++ b/aegisub/src/base_grid.cpp
@@ -34,9 +34,6 @@
/// @ingroup main_ui
///
-
-////////////
-// Includes
#include "config.h"
#ifndef AGI_PRE
@@ -56,7 +53,6 @@
#include "options.h"
#include "subs_edit_box.h"
#include "utils.h"
-#include "vfr.h"
#include "video_box.h"
#include "video_context.h"
#include "video_slider.h"
@@ -79,6 +75,7 @@ static inline void set_difference(const S1 &src1, const S2 &src2, D &dst) {
///
BaseGrid::BaseGrid(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name)
: wxWindow(parent, id, pos, size, style, name)
+, context(VideoContext::Get())
{
// Misc variables
lastRow = -1;
@@ -552,8 +549,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.GetFrameAtTime(curDiag->Start.GetMS(),true)));
- strings.Add(wxString::Format(_T("%i"),VFR_Output.GetFrameAtTime(curDiag->End.GetMS(),false)));
+ strings.Add(wxString::Format(_T("%i"),context->FrameAtTime(curDiag->Start.GetMS(),agi::vfr::START)));
+ strings.Add(wxString::Format(_T("%i"),context->FrameAtTime(curDiag->End.GetMS(),agi::vfr::END)));
}
else {
strings.Add(curDiag->Start.GetASSFormated());
@@ -787,7 +784,7 @@ void BaseGrid::OnMouseEvent(wxMouseEvent &event) {
// Normal click
if ((click || dclick) && !shift && !ctrl && !alt) {
SetActiveLine(dlg);
- if (dclick) VideoContext::Get()->JumpToTime(dlg->Start.GetMS());
+ if (dclick) context->JumpToTime(dlg->Start.GetMS());
SelectRow(row,false);
parentFrame->UpdateToolbar();
lastRow = row;
@@ -964,9 +961,9 @@ void BaseGrid::SetColumnWidths() {
// Times
if (byFrame) {
- int tmp = VFR_Output.GetFrameAtTime(curDiag->Start.GetMS(),true);
+ int tmp = context->FrameAtTime(curDiag->Start.GetMS(),agi::vfr::START);
if (tmp > maxStart) maxStart = tmp;
- tmp = VFR_Output.GetFrameAtTime(curDiag->End.GetMS(),true);
+ tmp = context->FrameAtTime(curDiag->End.GetMS(),agi::vfr::END);
if (tmp > maxEnd) maxEnd = tmp;
}
}
@@ -1053,8 +1050,8 @@ int BaseGrid::GetDialogueIndex(AssDialogue *diag) const {
bool BaseGrid::IsDisplayed(AssDialogue *line) {
VideoContext* con = VideoContext::Get();
if (!con->IsLoaded()) return false;
- int f1 = VFR_Output.GetFrameAtTime(line->Start.GetMS(),true);
- int f2 = VFR_Output.GetFrameAtTime(line->End.GetMS(),false);
+ int f1 = con->FrameAtTime(line->Start.GetMS(),agi::vfr::START);
+ int f2 = con->FrameAtTime(line->End.GetMS(),agi::vfr::END);
if (f1 <= con->GetFrameN() && f2 >= con->GetFrameN()) return true;
return false;
}
@@ -1106,7 +1103,7 @@ void BaseGrid::OnKeyPress(wxKeyEvent &event) {
// Left/right, forward to seek bar if video is loaded
if (key == WXK_LEFT || key == WXK_RIGHT) {
- if (VideoContext::Get()->IsLoaded()) {
+ if (context->IsLoaded()) {
parentFrame->videoBox->videoSlider->SetFocus();
parentFrame->videoBox->videoSlider->GetEventHandler()->ProcessEvent(event);
return;
@@ -1197,8 +1194,8 @@ void BaseGrid::OnKeyPress(wxKeyEvent &event) {
}
// Other events, send to audio display
- if (VideoContext::Get()->audio->loaded) {
- VideoContext::Get()->audio->GetEventHandler()->ProcessEvent(event);
+ if (context->audio->loaded) {
+ context->audio->GetEventHandler()->ProcessEvent(event);
}
else event.Skip();
}
diff --git a/aegisub/src/base_grid.h b/aegisub/src/base_grid.h
index 3f7256d7c..3e8ac2f61 100644
--- a/aegisub/src/base_grid.h
+++ b/aegisub/src/base_grid.h
@@ -37,8 +37,6 @@
#pragma once
-////////////
-// Includes
#ifndef AGI_PRE
#include
#include
@@ -49,13 +47,11 @@
#include "selection_controller.h"
-
-//////////////
-// Prototypes
class AssEntry;
class AssDialogue;
class SubsEditBox;
class FrameMain;
+class VideoContext;
/// DOCME
typedef std::list::iterator entryIter;
@@ -71,8 +67,6 @@ typedef SelectionListener SubtitleSelectionListener;
///
/// DOCME
class BaseGrid : public wxWindow, public BaseSelectionController {
-private:
-
/// DOCME
int lineHeight;
@@ -120,11 +114,12 @@ protected:
/// DOCME
FrameMain *parentFrame;
+ VideoContext *context;
+
/// DOCME
static const int columns = 10;
bool showCol[columns];
-
/// @brief DOCME
/// @param alternate
///
diff --git a/aegisub/src/dialog_jumpto.cpp b/aegisub/src/dialog_jumpto.cpp
index 40334161f..c31a01acc 100644
--- a/aegisub/src/dialog_jumpto.cpp
+++ b/aegisub/src/dialog_jumpto.cpp
@@ -34,9 +34,6 @@
/// @ingroup secondary_ui
///
-
-///////////
-// Headers
#include "config.h"
#ifndef AGI_PRE
@@ -50,36 +47,26 @@
#include "dialog_jumpto.h"
#include "libresrc/libresrc.h"
#include "utils.h"
-#include "vfr.h"
#include "video_context.h"
-
-///////
-// IDs
+/// Event IDs
enum {
-
- /// DOCME
TEXT_JUMP_TIME = 1100,
-
- /// DOCME
TEXT_JUMP_FRAME
};
-
-
/// @brief Constructor
/// @param parent
///
DialogJumpTo::DialogJumpTo (wxWindow *parent)
: wxDialog(parent, -1, _("Jump to"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxWANTS_CHARS , _T("JumpTo"))
{
- // Set icon
SetIcon(BitmapToIcon(GETIMAGE(jumpto_button_24)));
// Set initial values
ready = false;
jumpframe = VideoContext::Get()->GetFrameN();
- jumptime.SetMS(VFR_Output.GetTimeAtFrame(jumpframe,true,true));
+ jumptime.SetMS(VideoContext::Get()->TimeAtFrame(jumpframe));
wxString maxLength = wxString::Format(_T("%i"),VideoContext::Get()->GetLength()-1);
// Times
@@ -117,9 +104,6 @@ DialogJumpTo::DialogJumpTo (wxWindow *parent)
ready = true;
}
-
-///////////////
-// Event table
BEGIN_EVENT_TABLE(DialogJumpTo, wxDialog)
EVT_TEXT_ENTER(TEXT_JUMP_FRAME,DialogJumpTo::OnKey)
EVT_TEXT_ENTER(TEXT_JUMP_TIME,DialogJumpTo::OnKey)
@@ -129,42 +113,24 @@ BEGIN_EVENT_TABLE(DialogJumpTo, wxDialog)
EVT_TEXT(TEXT_JUMP_FRAME, DialogJumpTo::OnEditFrame)
END_EVENT_TABLE()
-
-
-/// @brief Close
-/// @param event
-///
-void DialogJumpTo::OnCloseButton (wxCommandEvent &event) { OnClose(false); }
-
-/// @brief DOCME
-/// @param event
-///
-void DialogJumpTo::OnOK (wxCommandEvent &event) { OnClose(true); }
-
-
+void DialogJumpTo::OnCloseButton (wxCommandEvent &) { OnClose(false); }
+void DialogJumpTo::OnOK (wxCommandEvent &) { OnClose(true); }
/// @brief On Key pressed
-/// @param event
-///
-void DialogJumpTo::OnKey(wxCommandEvent &event) {
+void DialogJumpTo::OnKey(wxCommandEvent &) {
EndModal(0);
if (jumpframe > VideoContext::Get()->GetLength()-1) jumpframe = VideoContext::Get()->GetLength()-1;
VideoContext::Get()->JumpToFrame(jumpframe);
}
-
-
/// @brief On OK button pressed
/// @param ok
-///
void DialogJumpTo::OnClose(bool ok) {
EndModal(0);
if (jumpframe > VideoContext::Get()->GetLength()-1) jumpframe = VideoContext::Get()->GetLength()-1;
if (ok) VideoContext::Get()->JumpToFrame(jumpframe);
}
-
-
/// @brief Time editbox changed
/// @param event
///
@@ -173,10 +139,10 @@ void DialogJumpTo::OnEditTime (wxCommandEvent &event) {
ready = false;
// Update frame
- long newframe = VFR_Output.GetFrameAtTime(JumpTime->time.GetMS());
+ long newframe = VideoContext::Get()->FrameAtTime(JumpTime->time.GetMS());
if (jumpframe != newframe) {
jumpframe = newframe;
- JumpFrame->SetValue(wxString::Format(_T("%i"),jumpframe));
+ JumpFrame->ChangeValue(wxString::Format(_T("%i"),jumpframe));
}
ready = true;
@@ -184,8 +150,6 @@ void DialogJumpTo::OnEditTime (wxCommandEvent &event) {
else event.Skip();
}
-
-
/// @brief Frame editbox changed
/// @param event
///
@@ -199,7 +163,7 @@ void DialogJumpTo::OnEditFrame (wxCommandEvent &event) {
JumpFrame->SetValue(wxString::Format(_T("%i"),jumpframe));
// Update time
- int newtime = VFR_Output.GetTimeAtFrame(jumpframe,true,true);
+ int newtime = VideoContext::Get()->TimeAtFrame(jumpframe);
if (jumptime.GetMS() != newtime) {
jumptime.SetMS(newtime);
JumpTime->ChangeValue(jumptime.GetASSFormated());
@@ -209,5 +173,3 @@ void DialogJumpTo::OnEditFrame (wxCommandEvent &event) {
}
else event.Skip();
}
-
-
diff --git a/aegisub/src/dialog_shift_times.cpp b/aegisub/src/dialog_shift_times.cpp
index 4a2043092..bdd28722b 100644
--- a/aegisub/src/dialog_shift_times.cpp
+++ b/aegisub/src/dialog_shift_times.cpp
@@ -61,10 +61,9 @@
#include "subs_edit_box.h"
#include "subs_grid.h"
#include "utils.h"
-#include "vfr.h"
+#include "video_context.h"
#include "video_display.h"
-
/// @brief Constructor
/// @param parent
/// @param _grid
@@ -92,7 +91,7 @@ DialogShiftTimes::DialogShiftTimes (wxWindow *parent,SubtitlesGrid *_grid)
ShiftTime->SetToolTip(_("Enter time in h:mm:ss.cs notation"));
RadioTime->SetToolTip(_("Shift by time"));
ShiftFrame->Disable();
- if (!VFR_Output.IsLoaded()) RadioFrames->Disable();
+ if (!VideoContext::Get()->TimecodesLoaded()) RadioFrames->Disable();
else {
ShiftFrame->SetToolTip(_("Enter number of frames to shift by"));
RadioFrames->SetToolTip(_("Shift by frames"));
diff --git a/aegisub/src/dialog_timing_processor.cpp b/aegisub/src/dialog_timing_processor.cpp
index 6abffcc22..d27cb3396 100644
--- a/aegisub/src/dialog_timing_processor.cpp
+++ b/aegisub/src/dialog_timing_processor.cpp
@@ -34,8 +34,6 @@
/// @ingroup tools_ui
///
-////////////
-// Includes
#include "config.h"
#include "ass_dialogue.h"
@@ -49,11 +47,20 @@
#include "subs_grid.h"
#include "utils.h"
#include "validators.h"
-#include "vfr.h"
#include "video_box.h"
#include "video_context.h"
#include "video_display.h"
+/// Window IDs
+enum {
+ CHECK_ENABLE_LEADIN = 1850,
+ CHECK_ENABLE_LEADOUT,
+ CHECK_ENABLE_KEYFRAME,
+ CHECK_ENABLE_ADJASCENT,
+ BUTTON_SELECT_ALL,
+ BUTTON_SELECT_NONE,
+ TIMING_STYLE_LIST
+};
/// @brief Constructor
/// @param parent
@@ -62,7 +69,6 @@
DialogTimingProcessor::DialogTimingProcessor(wxWindow *parent,SubtitlesGrid *_grid)
: wxDialog(parent,-1,_("Timing Post-Processor"),wxDefaultPosition,wxSize(400,250),wxDEFAULT_DIALOG_STYLE)
{
- // Set icon
SetIcon(BitmapToIcon(GETIMAGE(timing_processor_toolbutton_24)));
// Set variables
@@ -75,7 +81,6 @@ DialogTimingProcessor::DialogTimingProcessor(wxWindow *parent,SubtitlesGrid *_gr
thresEndAfter = AegiIntegerToString(OPT_GET("Tool/Timing Post Processor/Threshold/Key End After")->GetInt());
adjsThresTime = AegiIntegerToString(OPT_GET("Tool/Timing Post Processor/Threshold/Adjacent")->GetInt());
-
// Styles box
wxSizer *LeftSizer = new wxStaticBoxSizer(wxVERTICAL,this,_("Apply to styles"));
wxArrayString styles = grid->ass->GetStyles();
@@ -201,12 +206,9 @@ DialogTimingProcessor::DialogTimingProcessor(wxWindow *parent,SubtitlesGrid *_gr
CenterOnParent();
- // Update
UpdateControls();
}
-
-
/// @brief Update controls
///
void DialogTimingProcessor::UpdateControls() {
@@ -237,9 +239,6 @@ void DialogTimingProcessor::UpdateControls() {
ApplyButton->Enable(checked && (hasLeadIn->IsChecked() | hasLeadOut->IsChecked() | keysEnable->IsChecked() | adjsEnable->IsChecked()));
}
-
-///////////////
-// Event table
BEGIN_EVENT_TABLE(DialogTimingProcessor,wxDialog)
EVT_CHECKBOX(CHECK_ENABLE_LEADIN,DialogTimingProcessor::OnCheckBox)
EVT_CHECKBOX(CHECK_ENABLE_LEADOUT,DialogTimingProcessor::OnCheckBox)
@@ -251,21 +250,11 @@ BEGIN_EVENT_TABLE(DialogTimingProcessor,wxDialog)
EVT_BUTTON(BUTTON_SELECT_NONE,DialogTimingProcessor::OnSelectNone)
END_EVENT_TABLE()
-
-
-/// @brief Checkbox clicked
-/// @param event
-///
-void DialogTimingProcessor::OnCheckBox(wxCommandEvent &event) {
+void DialogTimingProcessor::OnCheckBox(wxCommandEvent &) {
UpdateControls();
}
-
-
-/// @brief Select all styles
-/// @param event
-///
-void DialogTimingProcessor::OnSelectAll(wxCommandEvent &event) {
+void DialogTimingProcessor::OnSelectAll(wxCommandEvent &) {
size_t len = StyleList->GetCount();
for (size_t i=0;iCheck(i);
@@ -273,12 +262,7 @@ void DialogTimingProcessor::OnSelectAll(wxCommandEvent &event) {
UpdateControls();
}
-
-
-/// @brief Unselect all styles
-/// @param event
-///
-void DialogTimingProcessor::OnSelectNone(wxCommandEvent &event) {
+void DialogTimingProcessor::OnSelectNone(wxCommandEvent &) {
size_t len = StyleList->GetCount();
for (size_t i=0;iCheck(i,false);
@@ -286,12 +270,7 @@ void DialogTimingProcessor::OnSelectNone(wxCommandEvent &event) {
UpdateControls();
}
-
-
-/// @brief Apply button pressed
-/// @param event
-///
-void DialogTimingProcessor::OnApply(wxCommandEvent &event) {
+void DialogTimingProcessor::OnApply(wxCommandEvent &) {
// Save settings
long temp = 0;
leadIn->GetValue().ToLong(&temp);
@@ -330,26 +309,16 @@ void DialogTimingProcessor::OnApply(wxCommandEvent &event) {
}
}
- // Process
if (valid) Process();
-
- // Error message
else wxMessageBox(wxString::Format(_("One of the lines in the file (%i) has negative duration. Aborting."),i),_("Invalid script"),wxICON_ERROR|wxOK);
- // Close dialogue
EndModal(0);
}
-
-
-/// @brief Get closest keyframe
-/// @param frame
-/// @return
-///
int DialogTimingProcessor::GetClosestKeyFrame(int frame) {
// Linear dumb search, not very efficient, but it doesn't really matter
int closest = 0;
- size_t n = KeyFrames.Count();
+ size_t n = KeyFrames.size();
for (size_t i=0;iIsChecked()) {
// Get keyframes
- KeyFrames = VideoContext::Get()->GetKeyFrames();
- KeyFrames.Add(VideoContext::Get()->GetLength()-1);
+ VideoContext *con = VideoContext::Get();
+ KeyFrames = con->GetKeyFrames();
+ KeyFrames.push_back(con->GetLength()-1);
// Variables
int startF,endF;
@@ -563,19 +524,19 @@ void DialogTimingProcessor::Process() {
cur = GetSortedDialogue(i);
// Get start/end frames
- startF = VFR_Output.GetFrameAtTime(cur->Start.GetMS(),true);
- endF = VFR_Output.GetFrameAtTime(cur->End.GetMS(),false);
+ startF = con->FrameAtTime(cur->Start.GetMS(),agi::vfr::START);
+ endF = con->FrameAtTime(cur->End.GetMS(),agi::vfr::END);
// Get closest for start
closest = GetClosestKeyFrame(startF);
if ((closest > startF && closest-startF <= beforeStart) || (closest < startF && startF-closest <= afterStart)) {
- cur->Start.SetMS(VFR_Output.GetTimeAtFrame(closest,true));
+ cur->Start.SetMS(con->TimeAtFrame(closest,agi::vfr::START));
}
// Get closest for end
closest = GetClosestKeyFrame(endF)-1;
if ((closest > endF && closest-endF <= beforeEnd) || (closest < endF && endF-closest <= afterEnd)) {
- cur->End.SetMS(VFR_Output.GetTimeAtFrame(closest,false));
+ cur->End.SetMS(con->TimeAtFrame(closest,agi::vfr::END));
}
}
}
@@ -584,5 +545,3 @@ void DialogTimingProcessor::Process() {
grid->ass->FlagAsModified(_("timing processor"));
grid->CommitChanges();
}
-
-
diff --git a/aegisub/src/dialog_timing_processor.h b/aegisub/src/dialog_timing_processor.h
index 7badb386b..08aff2bb8 100644
--- a/aegisub/src/dialog_timing_processor.h
+++ b/aegisub/src/dialog_timing_processor.h
@@ -34,11 +34,6 @@
/// @ingroup tools_ui
///
-
-
-
-///////////
-// Headers
#ifndef AGI_PRE
#include
@@ -51,33 +46,24 @@
#include
#endif
-
-//////////////
-// Prototypes
class SubtitlesGrid;
class AssDialogue;
-
-
/// DOCME
/// @class DialogTimingProcessor
/// @brief DOCME
///
/// DOCME
class DialogTimingProcessor : public wxDialog {
-private:
-
/// DOCME
SubtitlesGrid *grid;
/// DOCME
wxStaticBoxSizer *KeyframesSizer;
-
/// DOCME
wxCheckBox *onlySelection;
-
/// DOCME
wxTextCtrl *leadIn;
@@ -90,7 +76,6 @@ private:
/// DOCME
wxCheckBox *hasLeadOut;
-
/// DOCME
wxCheckBox *keysEnable;
@@ -106,7 +91,6 @@ private:
/// DOCME
wxTextCtrl *keysEndAfter;
-
/// DOCME
wxCheckBox *adjsEnable;
@@ -116,7 +100,6 @@ private:
/// DOCME
wxSlider *adjacentBias;
-
/// DOCME
wxCheckListBox *StyleList;
@@ -138,9 +121,8 @@ private:
/// DOCME
wxString leadInTime,leadOutTime,thresStartBefore,thresStartAfter,thresEndBefore,thresEndAfter,adjsThresTime;
-
/// DOCME
- wxArrayInt KeyFrames;
+ std::vector KeyFrames;
void OnCheckBox(wxCommandEvent &event);
void OnSelectAll(wxCommandEvent &event);
@@ -152,7 +134,6 @@ private:
int GetClosestKeyFrame(int frame);
bool StyleOK(wxString styleName);
-
/// DOCME
std::vector Sorted;
AssDialogue *GetSortedDialogue(int n);
@@ -163,30 +144,3 @@ public:
DECLARE_EVENT_TABLE()
};
-
-
-///////
-// IDs
-enum {
-
- /// DOCME
- CHECK_ENABLE_LEADIN = 1850,
-
- /// DOCME
- CHECK_ENABLE_LEADOUT,
-
- /// DOCME
- CHECK_ENABLE_KEYFRAME,
-
- /// DOCME
- CHECK_ENABLE_ADJASCENT,
-
- /// DOCME
- BUTTON_SELECT_ALL,
-
- /// DOCME
- BUTTON_SELECT_NONE,
-
- /// DOCME
- TIMING_STYLE_LIST
-};
diff --git a/aegisub/src/dialog_video_details.cpp b/aegisub/src/dialog_video_details.cpp
index 24d79dedd..59e65dcb7 100644
--- a/aegisub/src/dialog_video_details.cpp
+++ b/aegisub/src/dialog_video_details.cpp
@@ -66,7 +66,7 @@ DialogVideoDetails::DialogVideoDetails(wxWindow *parent)
int width = vprovider->GetWidth();
int height = vprovider->GetHeight();
int framecount = vprovider->GetFrameCount();
- double fps = vprovider->GetFPS();
+ double fps = vprovider->GetFPS().FPS();
wxTextCtrl *fname_text = new wxTextCtrl(this, -1, VideoContext::Get()->videoName, wxDefaultPosition, wxSize(300,-1), wxTE_READONLY);
wxTextCtrl *fps_text = new wxTextCtrl(this, -1, wxString::Format(_T("%.3f"), fps), wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
diff --git a/aegisub/src/export_framerate.cpp b/aegisub/src/export_framerate.cpp
index 8321f4629..47e03a132 100644
--- a/aegisub/src/export_framerate.cpp
+++ b/aegisub/src/export_framerate.cpp
@@ -53,6 +53,7 @@
#include "ass_override.h"
#include "export_framerate.h"
#include "utils.h"
+#include "video_context.h"
/// DOCME
/// @class LineData
@@ -93,11 +94,13 @@ void AssTransformFramerateFilter::ProcessSubs(AssFile *subs, wxWindow *export_di
wxWindow *AssTransformFramerateFilter::GetConfigDialogWindow(wxWindow *parent) {
wxWindow *base = new wxPanel(parent, -1);
+ LoadSettings(true);
+
// Input sizer
wxSizer *InputSizer = new wxBoxSizer(wxHORIZONTAL);
wxString initialInput;
wxButton *FromVideo = new wxButton(base,Get_Input_From_Video,_("From Video"));
- if (VFR_Input.IsLoaded()) initialInput = wxString::Format(_T("%2.3f"),VFR_Input.GetAverage());
+ if (Input->IsLoaded()) initialInput = wxString::Format(_T("%2.3f"),Input->FPS());
else {
initialInput = _T("23.976");
FromVideo->Enable(false);
@@ -119,7 +122,7 @@ wxWindow *AssTransformFramerateFilter::GetConfigDialogWindow(wxWindow *parent) {
// Output bottom line
RadioOutputCFR = new wxRadioButton(base,-1,_("Constant: "));
wxString initialOutput = initialInput;
- if (VFR_Output.GetFrameRateType() != VFR) {
+ if (!Output->IsVFR()) {
RadioOutputVFR->Enable(false);
RadioOutputCFR->SetValue(true);
}
@@ -150,20 +153,20 @@ wxWindow *AssTransformFramerateFilter::GetConfigDialogWindow(wxWindow *parent) {
void AssTransformFramerateFilter::LoadSettings(bool IsDefault) {
if (IsDefault) {
- Input = &VFR_Input;
- Output = &VFR_Output;
+ Input = &VideoContext::Get()->VFR_Input;
+ Output = &VideoContext::Get()->VFR_Output;
}
else {
double temp;
InputFramerate->GetValue().ToDouble(&temp);
- t1.SetCFR(temp);
+ t1 = temp;
Input = &t1;
if (RadioOutputCFR->GetValue()) {
OutputFramerate->GetValue().ToDouble(&temp);
- t2.SetCFR(temp);
+ t2 = temp;
Output = &t2;
}
- else Output = &VFR_Output;
+ else Output = &VideoContext::Get()->VFR_Output;
if (Reverse->IsChecked()) {
std::swap(Input, Output);
@@ -215,7 +218,7 @@ void AssTransformFramerateFilter::TransformTimeTags (wxString name,int n,AssOver
}
void AssTransformFramerateFilter::TransformFrameRate(AssFile *subs) {
- if (!Input->IsLoaded() || !Output->IsLoaded() || Input == Output || *Input == *Output) return;
+ if (!Input->IsLoaded() || !Output->IsLoaded()) return;
for (entryIter cur=subs->Line.begin();cur!=subs->Line.end();cur++) {
AssDialogue *curDialogue = dynamic_cast(*cur);
@@ -225,7 +228,7 @@ void AssTransformFramerateFilter::TransformFrameRate(AssFile *subs) {
data.newK = 0;
data.oldK = 0;
data.newStart = trunc_cs(ConvertTime(curDialogue->Start.GetMS()));
- data.newEnd = trunc_cs(ConvertTime(curDialogue->End.GetMS()));
+ data.newEnd = trunc_cs(ConvertTime(curDialogue->End.GetMS()) + 9);
// Process stuff
curDialogue->ParseASSTags();
@@ -239,16 +242,18 @@ void AssTransformFramerateFilter::TransformFrameRate(AssFile *subs) {
}
int AssTransformFramerateFilter::ConvertTime(int time) {
- int frame = Output->GetFrameAtTime(time, false);
- int frameStart = Output->GetTimeAtFrame(frame, false, true);
- int frameEnd = Output->GetTimeAtFrame(frame + 1, false, true);
+ int frame = Output->FrameAtTime(time);
+ int frameStart = Output->TimeAtFrame(frame);
+ int frameEnd = Output->TimeAtFrame(frame + 1);
int frameDur = frameEnd - frameStart;
double dist = double(time - frameStart) / frameDur;
- int newStart = Input->GetTimeAtFrame(frame, false, true);
- int newEnd = Input->GetTimeAtFrame(frame + 1, false, true);
+ int newStart = Input->TimeAtFrame(frame);
+ int newEnd = Input->TimeAtFrame(frame + 1);
int newDur = newEnd - newStart;
+ int dongs = Input->FrameAtTime(newStart + newDur * dist, agi::vfr::END);
+
return newStart + newDur * dist;
}
diff --git a/aegisub/src/export_framerate.h b/aegisub/src/export_framerate.h
index 2524b6528..5a6853952 100644
--- a/aegisub/src/export_framerate.h
+++ b/aegisub/src/export_framerate.h
@@ -35,7 +35,7 @@
///
#include "ass_export_filter.h"
-#include "vfr.h"
+#include
class AssDialogue;
class AssOverrideParameter;
@@ -51,10 +51,10 @@ class AssTransformFramerateFilter : public AssExportFilter {
static AssTransformFramerateFilter instance;
// Yes, these are backwards
- FrameRate *Input; /// Destination frame rate
- FrameRate *Output; /// Source frame rate
+ const agi::vfr::Framerate *Input; /// Destination frame rate
+ const agi::vfr::Framerate *Output; /// Source frame rate
- FrameRate t1,t2;
+ agi::vfr::Framerate t1,t2;
wxTextCtrl *InputFramerate; /// Input frame rate text box
wxTextCtrl *OutputFramerate; /// Output frame rate text box
diff --git a/aegisub/src/export_visible_lines.cpp b/aegisub/src/export_visible_lines.cpp
index 7e676d183..d0837b3d9 100644
--- a/aegisub/src/export_visible_lines.cpp
+++ b/aegisub/src/export_visible_lines.cpp
@@ -34,17 +34,13 @@
/// @ingroup export
///
-
-///////////
-// Headers
#include "config.h"
#include "ass_dialogue.h"
#include "ass_file.h"
#include "ass_override.h"
#include "export_visible_lines.h"
-#include "vfr.h"
-
+#include "video_context.h"
/// @brief Constructor
///
@@ -53,11 +49,6 @@ AssLimitToVisibleFilter::AssLimitToVisibleFilter() {
frame = -1;
}
-
-
-/// @brief Init
-/// @return
-///
void AssLimitToVisibleFilter::Init() {
if (initialized) return;
initialized = true;
@@ -67,15 +58,10 @@ void AssLimitToVisibleFilter::Init() {
description = _("Limit to Visible Lines");
}
-
-
/// @brief Process
/// @param subs
/// @param export_dialog
-/// @return
-///
void AssLimitToVisibleFilter::ProcessSubs(AssFile *subs, wxWindow *export_dialog) {
- // Nothing to do
if (frame == -1) return;
AssDialogue *diag;
@@ -86,8 +72,8 @@ void AssLimitToVisibleFilter::ProcessSubs(AssFile *subs, wxWindow *export_dialog
diag = dynamic_cast(*cur);
if (diag) {
// Invisible, remove frame
- if (VFR_Output.GetFrameAtTime(diag->Start.GetMS(),true) > frame ||
- VFR_Output.GetFrameAtTime(diag->End.GetMS(),false) < frame) {
+ if (VideoContext::Get()->FrameAtTime(diag->Start.GetMS(),agi::vfr::START) > frame ||
+ VideoContext::Get()->FrameAtTime(diag->End.GetMS(),agi::vfr::END) < frame) {
delete *cur;
subs->Line.erase(cur);
@@ -96,8 +82,6 @@ void AssLimitToVisibleFilter::ProcessSubs(AssFile *subs, wxWindow *export_dialog
}
}
-
-
/// @brief Set limitation time
/// @param _frame
///
@@ -105,9 +89,5 @@ void AssLimitToVisibleFilter::SetFrame(int _frame) {
instance.frame = _frame;
}
-
-
/// DOCME
AssLimitToVisibleFilter AssLimitToVisibleFilter::instance;
-
-
diff --git a/aegisub/src/frame_main.cpp b/aegisub/src/frame_main.cpp
index c2b8a77f8..eccd5a0d5 100644
--- a/aegisub/src/frame_main.cpp
+++ b/aegisub/src/frame_main.cpp
@@ -79,7 +79,6 @@
#include "text_file_writer.h"
#include "utils.h"
#include "version.h"
-#include "vfr.h"
#include "video_box.h"
#include "video_context.h"
#include "video_display.h"
@@ -642,6 +641,7 @@ void FrameMain::DeInitContents() {
AssFile::StackReset();
delete AssFile::top;
HelpButton::ClearPages();
+ VideoContext::Get()->audio = NULL;
}
/// @brief Update toolbar
@@ -760,6 +760,8 @@ void FrameMain::LoadSubtitles (wxString filename,wxString charset) {
// Update title bar
UpdateTitle();
+
+ VideoContext::Get()->Refresh();
}
/// @brief Save subtitles
@@ -949,7 +951,7 @@ void FrameMain::SynchronizeProject(bool fromSubs) {
int autoLoadMode = OPT_GET("App/Auto/Load Linked Files")->GetInt();
bool hasToLoad = false;
if (curSubsAudio != audioBox->audioName ||
- curSubsVFR != VFR_Output.GetFilename() ||
+ curSubsVFR != VideoContext::Get()->GetTimecodesName() ||
curSubsVideo != VideoContext::Get()->videoName ||
curSubsKeyframes != VideoContext::Get()->GetKeyFramesName()
#ifdef WITH_AUTOMATION
@@ -970,25 +972,18 @@ void FrameMain::SynchronizeProject(bool fromSubs) {
}
if (doLoad) {
- // Variable frame rate
- LoadVFR(curSubsVFR);
-
// Video
if (curSubsVideo != VideoContext::Get()->videoName) {
- //if (curSubsVideo != _T("")) {
LoadVideo(curSubsVideo);
if (VideoContext::Get()->IsLoaded()) {
VideoContext::Get()->SetAspectRatio(videoAr,videoArValue);
videoBox->videoDisplay->SetZoom(videoZoom);
VideoContext::Get()->JumpToFrame(videoPos);
}
- //}
}
- // Keyframes
- if (curSubsKeyframes != _T("")) {
- KeyFrameFile::Load(curSubsKeyframes);
- }
+ VideoContext::Get()->LoadTimecodes(curSubsVFR);
+ VideoContext::Get()->LoadKeyframes(curSubsKeyframes);
// Audio
if (curSubsAudio != audioBox->audioName) {
@@ -1058,7 +1053,7 @@ void FrameMain::SynchronizeProject(bool fromSubs) {
subs->SetScriptInfo(_T("Video Aspect Ratio"),ar);
subs->SetScriptInfo(_T("Video Zoom Percent"),zoom);
subs->SetScriptInfo(_T("Video Position"),seekpos);
- subs->SetScriptInfo(_T("VFR File"),MakeRelativePath(VFR_Output.GetFilename(),AssFile::top->filename));
+ subs->SetScriptInfo(_T("VFR File"),MakeRelativePath(VideoContext::Get()->GetTimecodesName(),AssFile::top->filename));
subs->SetScriptInfo(_T("Keyframes File"),MakeRelativePath(VideoContext::Get()->GetKeyFramesName(),AssFile::top->filename));
// Store Automation script data
@@ -1104,26 +1099,11 @@ void FrameMain::SynchronizeProject(bool fromSubs) {
void FrameMain::LoadVideo(wxString file,bool autoload) {
if (blockVideoLoad) return;
Freeze();
- VideoContext::Get()->Stop();
try {
- if (VideoContext::Get()->IsLoaded()) {
- if (VFR_Output.GetFrameRateType() == VFR) {
- if (!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();
- }
- }
- }
- else {
- VFR_Output.Unload();
- }
- }
VideoContext::Get()->SetVideo(file);
}
catch (const wchar_t *error) {
- wxString err(error);
- wxMessageBox(err, _T("Error opening video file"), wxOK | wxICON_ERROR, this);
+ wxMessageBox(error, _T("Error opening video file"), wxOK | wxICON_ERROR, this);
}
catch (...) {
wxMessageBox(_T("Unknown error"), _T("Error opening video file"), wxOK | wxICON_ERROR, this);
@@ -1199,43 +1179,17 @@ void FrameMain::LoadAudio(wxString filename,bool FromVideo) {
}
}
-/// @brief Loads VFR
-/// @param filename
void FrameMain::LoadVFR(wxString filename) {
- VideoContext::Get()->Stop();
- if (filename != _T("")) {
- try {
- VFR_Output.Load(filename);
- SubsGrid->Refresh(false);
- }
-
- // Fail
- catch (const wchar_t *error) {
- wxString err(error);
- wxMessageBox(err, _T("Error opening timecodes file"), wxOK | wxICON_ERROR, this);
- }
- catch (...) {
- wxMessageBox(_T("Unknown error"), _T("Error opening timecodes file"), wxOK | wxICON_ERROR, this);
- }
+ if (filename.empty()) {
+ VideoContext::Get()->CloseTimecodes();
}
-
else {
- VFR_Output.Unload();
- if (VideoContext::Get()->IsLoaded() && !VFR_Output.IsLoaded()) {
- VFR_Output.SetCFR(VideoContext::Get()->GetFPS());
- }
+ VideoContext::Get()->LoadTimecodes(filename);
}
-
SubsGrid->CommitChanges();
EditBox->UpdateFrameTiming();
}
-/// @brief Saves VFR
-/// @param filename
-void FrameMain::SaveVFR(wxString filename) {
- VFR_Output.Save(filename);
-}
-
/// @brief Open help
void FrameMain::OpenHelp(wxString) {
HelpButton::OpenPage(_T("Main"));
diff --git a/aegisub/src/frame_main.h b/aegisub/src/frame_main.h
index 98dc3c0e5..8b99921c9 100644
--- a/aegisub/src/frame_main.h
+++ b/aegisub/src/frame_main.h
@@ -315,7 +315,6 @@ private:
void LoadVideo(wxString filename,bool autoload=false);
void LoadAudio(wxString filename,bool FromVideo=false);
void LoadVFR(wxString filename);
- void SaveVFR(wxString filename);
void LoadSubtitles(wxString filename,wxString charset=_T(""));
bool SaveSubtitles(bool saveas=false,bool withCharset=false);
int TryToCloseSubs(bool enableCancel=true);
diff --git a/aegisub/src/frame_main_events.cpp b/aegisub/src/frame_main_events.cpp
index a8d7cdce4..baf014d06 100644
--- a/aegisub/src/frame_main_events.cpp
+++ b/aegisub/src/frame_main_events.cpp
@@ -89,7 +89,6 @@
#include "subs_grid.h"
#include "toggle_bitmap.h"
#include "utils.h"
-#include "vfr.h"
#include "video_box.h"
#include "video_context.h"
#include "video_display.h"
@@ -336,8 +335,8 @@ void FrameMain::OnMenuOpen (wxMenuEvent &event) {
MenuBar->Enable(Menu_Video_AR_235,attached);
MenuBar->Enable(Menu_Video_AR_Custom,attached);
MenuBar->Enable(Menu_Video_Detach,state);
- MenuBar->Enable(Menu_File_Save_VFR,VFR_Output.GetFrameRateType() == VFR);
- MenuBar->Enable(Menu_File_Close_VFR,VFR_Output.GetFrameRateType() == VFR);
+ MenuBar->Enable(Menu_File_Save_VFR,VideoContext::Get()->TimecodesLoaded());
+ MenuBar->Enable(Menu_File_Close_VFR,VideoContext::Get()->OverTimecodesLoaded());
MenuBar->Enable(Menu_Video_Close_Keyframes,VideoContext::Get()->OverKeyFramesLoaded());
MenuBar->Enable(Menu_Video_Save_Keyframes,VideoContext::Get()->KeyFramesLoaded());
MenuBar->Enable(Menu_Video_Details,state);
@@ -399,7 +398,7 @@ void FrameMain::OnMenuOpen (wxMenuEvent &event) {
MenuBar->Enable(Menu_Subtitles_Insert,state);
state = count > 0 && continuous;
MenuBar->Enable(MENU_DUPLICATE,state);
- state = count > 0 && continuous && VFR_Output.IsLoaded();
+ state = count > 0 && continuous && VideoContext::Get()->TimecodesLoaded();
MenuBar->Enable(MENU_DUPLICATE_NEXT_FRAME,state);
state = count == 2;
MenuBar->Enable(MENU_SWAP,state);
@@ -540,7 +539,7 @@ void FrameMain::OnOpenRecentTimecodes(wxCommandEvent &event) {
/// @param event
void FrameMain::OnOpenRecentKeyframes(wxCommandEvent &event) {
int number = event.GetId()-Menu_Keyframes_Recent;
- KeyFrameFile::Load(lagi_wxString(config::mru->GetEntry("Keyframes", number)));
+ VideoContext::Get()->LoadKeyframes(lagi_wxString(config::mru->GetEntry("Keyframes", number)));
videoBox->videoSlider->Refresh();
audioBox->audioDisplay->Update();
Refresh();
@@ -789,7 +788,7 @@ void FrameMain::OnSaveVFR(wxCommandEvent &) {
+ _("All Files") + _T(" (*.*)|*.*");
wxString filename = wxFileSelector(_("Save timecodes file"),path,_T(""),_T(""),str,wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
if (!filename.empty()) {
- SaveVFR(filename);
+ VideoContext::Get()->SaveTimecodes(filename);
OPT_SET("Path/Last/Timecodes")->SetString(STD_STR(filename));
}
}
@@ -797,19 +796,26 @@ void FrameMain::OnSaveVFR(wxCommandEvent &) {
/// @brief Close VFR tags
void FrameMain::OnCloseVFR(wxCommandEvent &) {
- LoadVFR(_T(""));
+ LoadVFR("");
}
/// @brief Open keyframes
void FrameMain::OnOpenKeyframes (wxCommandEvent &) {
// Pick file
wxString path = lagi_wxString(OPT_GET("Path/Last/Keyframes")->GetString());
- wxString filename = wxFileSelector(_T("Select the keyframes file to open"),path,_T(""),_T(".txt"),_T("All supported formats (*.txt, *.pass, *.stats, *.log)|*.txt;*.pass;*.stats;*.log|All files (*.*)|*.*"),wxFD_FILE_MUST_EXIST | wxFD_OPEN);
- if (filename.IsEmpty()) return;
+ wxString filename = wxFileSelector(
+ _T("Select the keyframes file to open"),
+ path,
+ _T("")
+ ,_T(".txt"),
+ _T("All supported formats (*.txt, *.pass, *.stats, *.log)|*.txt;*.pass;*.stats;*.log|All files (*.*)|*.*"),
+ wxFD_FILE_MUST_EXIST | wxFD_OPEN);
+
+ if (filename.empty()) return;
OPT_SET("Path/Last/Keyframes")->SetString(STD_STR(filename));
// Load
- KeyFrameFile::Load(filename);
+ VideoContext::Get()->LoadKeyframes(filename);
videoBox->videoSlider->Refresh();
audioBox->audioDisplay->Update();
Refresh();
@@ -817,7 +823,7 @@ void FrameMain::OnOpenKeyframes (wxCommandEvent &) {
/// @brief Close keyframes
void FrameMain::OnCloseKeyframes (wxCommandEvent &) {
- VideoContext::Get()->CloseOverKeyFrames();
+ VideoContext::Get()->CloseKeyframes();
videoBox->videoSlider->Refresh();
audioBox->audioDisplay->Update();
Refresh();
@@ -831,8 +837,7 @@ void FrameMain::OnSaveKeyframes (wxCommandEvent &) {
if (filename.IsEmpty()) return;
OPT_SET("Path/Last/Keyframes")->SetString(STD_STR(filename));
- // Save
- KeyFrameFile::Save(filename);
+ VideoContext::Get()->SaveKeyframes(filename);
}
/// @brief Zoom levels
@@ -1064,118 +1069,100 @@ void FrameMain::OnAutomationMacro (wxCommandEvent &event) {
/// @brief Snap subs to video
void FrameMain::OnSnapSubsStartToVid (wxCommandEvent &) {
- if (VideoContext::Get()->IsLoaded() && SubsGrid->GetSelection().Count() > 0) {
- SubsGrid->SetSubsToVideo(true);
- }
+ SubsGrid->SetSubsToVideo(true);
}
-
/// @brief DOCME
void FrameMain::OnSnapSubsEndToVid (wxCommandEvent &) {
- if (VideoContext::Get()->IsLoaded() && SubsGrid->GetSelection().Count() > 0) {
- SubsGrid->SetSubsToVideo(false);
- }
+ SubsGrid->SetSubsToVideo(false);
}
/// @brief Jump video to subs
void FrameMain::OnSnapVidToSubsStart (wxCommandEvent &) {
- if (VideoContext::Get()->IsLoaded() && SubsGrid->GetSelection().Count() > 0) {
- SubsGrid->SetVideoToSubs(true);
- }
+ SubsGrid->SetVideoToSubs(true);
}
/// @brief DOCME
void FrameMain::OnSnapVidToSubsEnd (wxCommandEvent &) {
- if (VideoContext::Get()->IsLoaded() && SubsGrid->GetSelection().Count() > 0) {
- SubsGrid->SetVideoToSubs(false);
- }
+ SubsGrid->SetVideoToSubs(false);
}
/// @brief Snap to scene
void FrameMain::OnSnapToScene (wxCommandEvent &) {
- if (VideoContext::Get()->IsLoaded()) {
- // Get frames
- wxArrayInt sel = SubsGrid->GetSelection();
- int curFrame = VideoContext::Get()->GetFrameN();
- int prev = 0;
- int next = 0;
- int frame = 0;
- wxArrayInt keyframes = VideoContext::Get()->GetKeyFrames();
- size_t n = keyframes.Count();
- bool found = false;
- for (size_t i=0;iIsLoaded() || !con->KeyFramesLoaded()) return;
- if (frame == curFrame) {
- prev = frame;
- if (i < n-1) next = keyframes[i+1];
- else next = VideoContext::Get()->GetLength();
- found = true;
- break;
- }
+ // Get frames
+ wxArrayInt sel = SubsGrid->GetSelection();
+ int curFrame = con->GetFrameN();
+ int prev = 0;
+ int next = 0;
- if (frame > curFrame) {
- if (i != 0) prev = keyframes[i-1];
- else prev = 0;
- next = frame;
- found = true;
- break;
- }
- }
-
- // Last section?
- if (!found) {
- if (n > 0) prev = keyframes[n-1];
- else prev = 0;
- next = VideoContext::Get()->GetLength();
- }
-
- // Get times
- int start_ms = VFR_Output.GetTimeAtFrame(prev,true);
- int end_ms = VFR_Output.GetTimeAtFrame(next-1,false);
- AssDialogue *cur;
-
- // Update rows
- for (size_t i=0;iGetDialogue(sel[i]);
- cur->Start.SetMS(start_ms);
- cur->End.SetMS(end_ms);
- }
-
- // Commit
- SubsGrid->editBox->Update(true);
- SubsGrid->ass->FlagAsModified(_("snap to scene"));
- SubsGrid->CommitChanges();
+ const std::vector &keyframes = con->GetKeyFrames();
+ if (curFrame < keyframes.front()) {
+ next = keyframes.front();
}
+ else if (curFrame >= keyframes.back()) {
+ prev = keyframes.back();
+ next = con->GetLength();
+ }
+ else {
+ std::vector::const_iterator kf = std::lower_bound(keyframes.begin(), keyframes.end(), curFrame);
+ if (*kf == curFrame) {
+ prev = *kf;
+ next = *(kf + 1);
+ }
+ else {
+ prev = *(kf - 1);
+ next = *kf;
+ }
+ }
+
+ // Get times
+ int start_ms = con->TimeAtFrame(prev,agi::vfr::START);
+ int end_ms = con->TimeAtFrame(next-1,agi::vfr::END);
+ AssDialogue *cur;
+
+ // Update rows
+ for (size_t i=0;iGetDialogue(sel[i]);
+ cur->Start.SetMS(start_ms);
+ cur->End.SetMS(end_ms);
+ }
+
+ // Commit
+ SubsGrid->editBox->Update(true);
+ SubsGrid->ass->FlagAsModified(_("snap to scene"));
+ SubsGrid->CommitChanges();
}
/// @brief Shift to frame
void FrameMain::OnShiftToFrame (wxCommandEvent &) {
- if (VideoContext::Get()->IsLoaded()) {
- wxArrayInt sels = SubsGrid->GetSelection();
- size_t n=sels.Count();
- if (n == 0) return;
+ if (!VideoContext::Get()->IsLoaded()) return;
- // Get shifting in ms
- AssDialogue *cur = SubsGrid->GetDialogue(sels[0]);
- if (!cur) return;
- int shiftBy = VFR_Output.GetTimeAtFrame(VideoContext::Get()->GetFrameN(),true) - cur->Start.GetMS();
+ wxArrayInt sels = SubsGrid->GetSelection();
+ size_t n=sels.Count();
+ if (n == 0) return;
- // Update
- for (size_t i=0;iGetDialogue(sels[i]);
- if (cur) {
- cur->Start.SetMS(cur->Start.GetMS()+shiftBy);
- cur->End.SetMS(cur->End.GetMS()+shiftBy);
- }
+ // Get shifting in ms
+ AssDialogue *cur = SubsGrid->GetDialogue(sels[0]);
+ if (!cur) return;
+ int shiftBy = VideoContext::Get()->TimeAtFrame(VideoContext::Get()->GetFrameN(),agi::vfr::START) - cur->Start.GetMS();
+
+ // Update
+ for (size_t i=0;iGetDialogue(sels[i]);
+ if (cur) {
+ cur->Start.SetMS(cur->Start.GetMS()+shiftBy);
+ cur->End.SetMS(cur->End.GetMS()+shiftBy);
}
-
- // Commit
- SubsGrid->ass->FlagAsModified(_("shift to frame"));
- SubsGrid->CommitChanges();
- SubsGrid->editBox->Update(true,false);
}
+
+ // Commit
+ SubsGrid->ass->FlagAsModified(_("shift to frame"));
+ SubsGrid->CommitChanges();
+ SubsGrid->editBox->Update(true,false);
}
/// @brief Undo
diff --git a/aegisub/src/include/aegisub/video_provider.h b/aegisub/src/include/aegisub/video_provider.h
index 185e8df1c..f01b0a10c 100644
--- a/aegisub/src/include/aegisub/video_provider.h
+++ b/aegisub/src/include/aegisub/video_provider.h
@@ -34,16 +34,10 @@
/// @ingroup main_headers video_input
///
-
#pragma once
-
-//////////
-// Headers
-#include "aegisub.h"
-#include "vfr.h"
#include "video_frame.h"
-
+#include
/// @class VideoProvider
/// @brief DOCME
@@ -51,62 +45,31 @@
/// DOCME
class VideoProvider {
public:
-
- /// @brief // Virtual destructor
- /// @return
- ///
virtual ~VideoProvider() {}
// Override this method to actually get frames
virtual const AegiVideoFrame GetFrame(int n)=0;
// Override the following methods to get video information:
- virtual int GetPosition()=0; // Get the number of the last frame loaded
- virtual int GetFrameCount()=0; // Get total number of frames
- virtual int GetWidth()=0; // Returns the video width in pixels
- virtual int GetHeight()=0; // Returns the video height in pixels
- virtual double GetFPS()=0; // Get framerate in frames per second
- virtual bool AreKeyFramesLoaded()=0; // Returns true if keyframe info is loaded, false otherwise
- virtual bool IsVFR()=0; // Returns true if video is VFR
- virtual wxArrayInt GetKeyFrames()=0; // Returns list of keyframes
- virtual FrameRate GetTrueFrameRate()=0; // Returns magic VFR stuff
+ virtual int GetPosition() const=0; ///< Get the number of the last frame loaded
+ virtual int GetFrameCount() const=0; ///< Get total number of frames
+ virtual int GetWidth() const=0; ///< Returns the video width in pixels
+ virtual int GetHeight() const=0; ///< Returns the video height in pixels
+ virtual agi::vfr::Framerate GetFPS() const=0; ///< Get frame rate
+ virtual std::vector GetKeyFrames() const=0;///< Returns list of keyframes
- /// @brief // Use this to set any post-loading warnings, such as "being loaded with unreliable seeking"
- /// @return
- ///
- virtual wxString GetWarning() { return L""; }
-
-
- /// @brief // Name of decoder, e.g. "Avisynth/FFMpegSource"
- /// @return
- ///
- virtual wxString GetDecoderName() { return L"Unknown"; }
+ /// @brief Use this to set any post-loading warnings, such as "being loaded with unreliable seeking"
+ virtual wxString GetWarning() const { return L""; }
+ /// @brief Name of decoder, e.g. "Avisynth/FFMpegSource"
+ virtual wxString GetDecoderName() const = 0;
/// @brief Does this provider want Aegisub to cache video frames?
/// @return Returns true if caching is desired, false otherwise.
- virtual bool WantsCaching() { return false; }
-
-
- /// @brief // For "special" providers that don't deal well with VFR (i.e. Avisynth)
- /// @return
- ///
- virtual bool NeedsVFRHack() { return false; }; // Returns true if provider needs special VFR treatment
-
- /// @brief DOCME
- /// @return
- ///
- virtual bool IsNativelyByFrames() { return true; };
-
- /// @brief DOCME
- /// @param list
- ///
- virtual void OverrideFrameTimeList(std::vector list) {} // Override the list with the provided one, for VFR handling
+ virtual bool WantsCaching() const { return false; }
};
-
-
/// @class VideoProviderFactory
/// @brief DOCME
///
@@ -119,5 +82,3 @@ public:
virtual ~VideoProviderFactory() {}
virtual VideoProvider *CreateProvider(wxString video)=0;
};
-
-
diff --git a/aegisub/src/keyframe.cpp b/aegisub/src/keyframe.cpp
index 4eb1b590d..1a8252b1e 100644
--- a/aegisub/src/keyframe.cpp
+++ b/aegisub/src/keyframe.cpp
@@ -34,8 +34,6 @@
/// @ingroup video_input
///
-///////////
-// Headers
#include "config.h"
#ifndef AGI_PRE
@@ -48,19 +46,11 @@
#include "options.h"
#include "text_file_reader.h"
#include "text_file_writer.h"
-#include "vfr.h"
#include "video_context.h"
-
-/// @brief Load Keyframes
-/// @param filename
-///
-void KeyFrameFile::Load(wxString filename) {
- // Load
+std::vector KeyFrameFile::Load(wxString filename) {
try {
- // Open file
- wxArrayInt keyFrames;
- keyFrames.Empty();
+ std::vector keyFrames;
TextFileReader file(filename,_T("ASCII"));
wxString cur = file.ReadLineFromFile();
@@ -71,53 +61,36 @@ void KeyFrameFile::Load(wxString filename) {
else if (cur.StartsWith(_T("#options:"))) { Openx264KeyFrames(file, keyFrames); }
else { throw(_T("Invalid or unsupported keyframes file.")); }
- // Set keyframes
- VideoContext::Get()->SetOverKeyFrames(keyFrames);
- VideoContext::Get()->SetKeyFramesName(filename);
-
- // Add to recent
config::mru->Add("Keyframes", STD_STR(filename));
+ return keyFrames;
}
// Fail
catch (const wchar_t *error) {
- wxString err(error);
- wxMessageBox(err, _T("Error opening keyframes file"), wxOK | wxICON_ERROR, NULL);
+ wxMessageBox(error, _T("Error opening keyframes file"), wxOK | wxICON_ERROR, NULL);
}
catch (...) {
wxMessageBox(_T("Unknown error"), _T("Error opening keyframes file"), wxOK | wxICON_ERROR, NULL);
}
+ return std::vector();
}
-
-
-/// @brief Save Keyframes
-/// @param filename
-///
-void KeyFrameFile::Save(wxString filename) {
- // Get keyframes
- wxArrayInt keyFrames = VideoContext::Get()->GetKeyFrames();
-
- // Write header
+void KeyFrameFile::Save(wxString filename, std::vector const& keyFrames) {
TextFileWriter file(filename,_T("ASCII"));
file.WriteLineToFile(_T("# keyframe format v1"));
- file.WriteLineToFile(wxString::Format(_T("fps %f"),VideoContext::Get()->GetFPS()));
+ file.WriteLineToFile(wxString::Format(_T("fps %f"),VideoContext::Get()->VFR_Input.FPS()));
- // Write keyframes
- for (unsigned int i=0;iAdd("Keyframes", STD_STR(filename));
}
-
-
/// @brief Aegisub keyframes file
/// @param file
/// @param keyFrames
///
-void KeyFrameFile::OpenAegiKeyFrames(TextFileReader& file, wxArrayInt& keyFrames)
+void KeyFrameFile::OpenAegiKeyFrames(TextFileReader& file, std::vector& keyFrames)
{
double fps;
wxString cur = file.ReadLineFromFile();
@@ -129,10 +102,8 @@ void KeyFrameFile::OpenAegiKeyFrames(TextFileReader& file, wxArrayInt& keyFrames
if (fps == 0.0) throw _T("Invalid FPS.");
// Set FPS
- if (!VideoContext::Get()->IsLoaded()) {
- VideoContext::Get()->SetFPS(fps);
- VFR_Input.SetCFR(fps);
- if (!VFR_Output.IsLoaded()) VFR_Output.SetCFR(fps);
+ if (!VideoContext::Get()->TimecodesLoaded()) {
+ VideoContext::Get()->ovrFPS = fps;
}
// Read lines
@@ -141,26 +112,24 @@ void KeyFrameFile::OpenAegiKeyFrames(TextFileReader& file, wxArrayInt& keyFrames
if (!cur.IsEmpty() && !cur.StartsWith(_T("#")) && cur.IsNumber()) {
long temp;
cur.ToLong(&temp);
- keyFrames.Add(temp);
+ keyFrames.push_back(temp);
}
- }
+ }
}
-
-
/// @brief XviD stats file
/// @param file
/// @param keyFrames
///
-void KeyFrameFile::OpenXviDKeyFrames(TextFileReader& file, wxArrayInt& keyFrames)
+void KeyFrameFile::OpenXviDKeyFrames(TextFileReader& file, std::vector& keyFrames)
{
wxString cur = file.ReadLineFromFile();
unsigned int count = 0;
// Read lines
while (file.HasMoreLines()) {
- if (cur.StartsWith(_T("i"))) {
- keyFrames.Add(count);
+ if (cur.StartsWith(_T("i"))) {
+ keyFrames.push_back(count);
count++;
}
else if (cur.StartsWith(_T("p")) || cur.StartsWith(_T("b"))) {
@@ -170,12 +139,11 @@ void KeyFrameFile::OpenXviDKeyFrames(TextFileReader& file, wxArrayInt& keyFrames
}
}
-
/// @brief DivX stats file
/// @param file
/// @param keyFrames
///
-void KeyFrameFile::OpenDivXKeyFrames(TextFileReader& file, wxArrayInt& keyFrames)
+void KeyFrameFile::OpenDivXKeyFrames(TextFileReader& file, std::vector& keyFrames)
{
wxString cur = file.ReadLineFromFile();
unsigned int count = 0;
@@ -184,7 +152,7 @@ void KeyFrameFile::OpenDivXKeyFrames(TextFileReader& file, wxArrayInt& keyFrames
while (file.HasMoreLines())
{
if (cur.Contains(_T("I"))) {
- keyFrames.Add(count);
+ keyFrames.push_back(count);
count++;
}
else if (cur.Contains(_T("P")) || cur.Contains(_T("B"))) {
@@ -194,12 +162,11 @@ void KeyFrameFile::OpenDivXKeyFrames(TextFileReader& file, wxArrayInt& keyFrames
}
}
-
/// @brief x264 stats file
/// @param file
/// @param keyFrames
///
-void KeyFrameFile::Openx264KeyFrames(TextFileReader& file, wxArrayInt& keyFrames)
+void KeyFrameFile::Openx264KeyFrames(TextFileReader& file, std::vector& keyFrames)
{
wxString cur = file.ReadLineFromFile();
unsigned int count = 0;
@@ -210,7 +177,7 @@ void KeyFrameFile::Openx264KeyFrames(TextFileReader& file, wxArrayInt& keyFrames
{
pos = cur.Find(_T("type:"));
if (cur.Mid(pos,6).Right(1).Lower() == (_T("i"))) {
- keyFrames.Add(count);
+ keyFrames.push_back(count);
count++;
}
else if (cur.Mid(pos,6).Right(1).Lower() == (_T("p")) || cur.Mid(pos,6).Right(1).Lower() == (_T("b"))) {
@@ -219,5 +186,3 @@ void KeyFrameFile::Openx264KeyFrames(TextFileReader& file, wxArrayInt& keyFrames
cur = file.ReadLineFromFile();
}
}
-
-
diff --git a/aegisub/src/keyframe.h b/aegisub/src/keyframe.h
index c8f146690..82af544da 100644
--- a/aegisub/src/keyframe.h
+++ b/aegisub/src/keyframe.h
@@ -34,9 +34,6 @@
/// @ingroup video_input
///
-
-///////////
-// Headers
#include "text_file_reader.h"
@@ -48,13 +45,13 @@
class KeyFrameFile
{
public:
- static void Load(wxString filename);
- static void Save(wxString filename);
+ static std::vector Load(wxString filename);
+ static void Save(wxString filename, std::vector const& keyframes);
private:
- static void OpenAegiKeyFrames(TextFileReader& file, wxArrayInt& keyFrames);
- static void OpenXviDKeyFrames(TextFileReader& file, wxArrayInt& keyFrames);
- static void OpenDivXKeyFrames(TextFileReader& file, wxArrayInt& keyFrames);
- static void Openx264KeyFrames(TextFileReader& file, wxArrayInt& keyFrames);
+ static void OpenAegiKeyFrames(TextFileReader& file, std::vector& keyFrames);
+ static void OpenXviDKeyFrames(TextFileReader& file, std::vector& keyFrames);
+ static void OpenDivXKeyFrames(TextFileReader& file, std::vector& keyFrames);
+ static void Openx264KeyFrames(TextFileReader& file, std::vector& keyFrames);
};
diff --git a/aegisub/src/main.cpp b/aegisub/src/main.cpp
index f6d6ebc1d..f08b032d5 100644
--- a/aegisub/src/main.cpp
+++ b/aegisub/src/main.cpp
@@ -280,7 +280,6 @@ bool AegisubApp::OnInit() {
///
int AegisubApp::OnExit() {
SubtitleFormat::DestroyFormats();
- VideoContext::Clear();
delete plugins;
delete config::opt;
delete config::mru;
diff --git a/aegisub/src/mkv_wrap.cpp b/aegisub/src/mkv_wrap.cpp
index bb91a7193..885371f48 100644
--- a/aegisub/src/mkv_wrap.cpp
+++ b/aegisub/src/mkv_wrap.cpp
@@ -34,9 +34,6 @@
/// @ingroup video_input
///
-
-///////////
-// Headers
#include "config.h"
#ifndef AGI_PRE
@@ -44,6 +41,7 @@
#include
#include
+#include
#include
#include
@@ -53,6 +51,7 @@
#include "ass_file.h"
#include "ass_time.h"
#include "dialog_progress.h"
+#include
#include "mkv_wrap.h"
@@ -259,51 +258,21 @@ void MatroskaWrapper::Parse() {
}
+static int mkv_round(double num) {
+ return (int)(num + .5);
+}
/// @brief Set target to timecodes
/// @param target
/// @return
///
-void MatroskaWrapper::SetToTimecodes(FrameRate &target) {
- // Enough frames?
- int frames = timecodes.size();
- if (frames <= 1) return;
+void MatroskaWrapper::SetToTimecodes(agi::vfr::Framerate &target) {
+ if (timecodes.size() <= 1) return;
- // Sort
- //std::sort::iterator>(timecodes.begin(),timecodes.end());
-
- // Check if it's CFR
- /*
- bool isCFR = true;
- double estimateCFR = timecodes.back() / (timecodes.size()-1);
- double t1,t2;
- for (int i=1;i 2) {
- isCFR = false;
- break;
- }
- }
- */
- bool isCFR = false;
- double estimateCFR = 0;
-
- // Constant framerate
- if (isCFR) {
- estimateCFR = 1/estimateCFR * 1000.0;
- if (fabs(estimateCFR - 24000.0/1001.0) < 0.02) estimateCFR = 24000.0 / 1001.0;
- if (fabs(estimateCFR - 30000.0/1001.0) < 0.02) estimateCFR = 30000.0 / 1001.0;
- target.SetCFR(estimateCFR);
- }
-
- // Variable framerate
- else {
- std::vector times;
- for (int i=0;i times;
+ times.reserve(timecodes.size());
+ std::transform(timecodes.begin(), timecodes.end(), std::back_inserter(times), &mkv_round);
+ target = agi::vfr::Framerate(times);
}
diff --git a/aegisub/src/mkv_wrap.h b/aegisub/src/mkv_wrap.h
index 062ceecc6..369d576ab 100644
--- a/aegisub/src/mkv_wrap.h
+++ b/aegisub/src/mkv_wrap.h
@@ -34,11 +34,6 @@
/// @ingroup video_input
///
-
-
-
-///////////
-// Headers
#ifndef AGI_PRE
#include
#include
@@ -48,14 +43,9 @@
#endif
#include "MatroskaParser.h"
-#include "vfr.h"
-
-//////////////
-// Prototypes
class AssFile;
-
-
+namespace agi { namespace vfr { class Framerate; } }
/// DOCME
/// @class MkvStdIO
@@ -161,7 +151,7 @@ public:
void Close();
void Parse();
- void SetToTimecodes(FrameRate &target);
+ void SetToTimecodes(agi::vfr::Framerate &target);
/// @brief DOCME
/// @return
diff --git a/aegisub/src/subs_edit_box.cpp b/aegisub/src/subs_edit_box.cpp
index 063d20238..9c243dd40 100644
--- a/aegisub/src/subs_edit_box.cpp
+++ b/aegisub/src/subs_edit_box.cpp
@@ -299,9 +299,6 @@ void SubsEditBox::Update (bool timeOnly,bool weak) {
// Audio
if (!weak) audio->SetDialogue(grid,curdiag,grid->GetDialogueIndex(curdiag));
- // Video
- VideoContext::Get()->curLine = curdiag;
-
TextEdit->EmptyUndoBuffer();
}
else enabled = false;
@@ -550,7 +547,7 @@ void SubsEditBox::SetControlsState (bool state) {
/// @brief Disables or enables frame timing
///
void SubsEditBox::UpdateFrameTiming () {
- if (VideoContext::Get()->IsLoaded()) ByFrame->Enable(enabled);
+ if (VideoContext::Get()->TimecodesLoaded()) ByFrame->Enable(enabled);
else {
ByFrame->Enable(false);
ByTime->SetValue(true);
diff --git a/aegisub/src/subs_grid.cpp b/aegisub/src/subs_grid.cpp
index a985465dc..09b7b5718 100644
--- a/aegisub/src/subs_grid.cpp
+++ b/aegisub/src/subs_grid.cpp
@@ -34,9 +34,6 @@
/// @ingroup main_ui
///
-
-////////////
-// Includes
#include "config.h"
#ifndef AGI_PRE
@@ -61,13 +58,9 @@
#include "subs_edit_box.h"
#include "subs_grid.h"
#include "utils.h"
-#include "vfr.h"
#include "video_context.h"
#include "video_display.h"
-
-///////////////
-// Event table
BEGIN_EVENT_TABLE(SubtitlesGrid, BaseGrid)
EVT_KEY_DOWN(SubtitlesGrid::OnKeyDown)
EVT_MENU(MENU_SWAP,SubtitlesGrid::OnSwap)
@@ -171,14 +164,14 @@ void SubtitlesGrid::OnPopupMenu(bool alternate) {
state = (sels == 1);
menu.Append(MENU_INSERT_BEFORE,_("&Insert (before)"),_T("Inserts a line before current"))->Enable(state);
menu.Append(MENU_INSERT_AFTER,_("Insert (after)"),_T("Inserts a line after current"))->Enable(state);
- state = (sels == 1 && VideoContext::Get()->IsLoaded());
+ state = (sels == 1 && context->IsLoaded());
menu.Append(MENU_INSERT_BEFORE_VIDEO,_("Insert at video time (before)"),_T("Inserts a line after current, starting at video time"))->Enable(state);
menu.Append(MENU_INSERT_AFTER_VIDEO,_("Insert at video time (after)"),_T("Inserts a line after current, starting at video time"))->Enable(state);
menu.AppendSeparator();
// Duplicate selection
menu.Append(MENU_DUPLICATE,_("&Duplicate"),_("Duplicate the selected lines"))->Enable(continuous);
- menu.Append(MENU_DUPLICATE_NEXT_FRAME,_("&Duplicate and shift by 1 frame"),_("Duplicate lines and shift by one frame"))->Enable(continuous && VFR_Output.IsLoaded());
+ menu.Append(MENU_DUPLICATE_NEXT_FRAME,_("&Duplicate and shift by 1 frame"),_("Duplicate lines and shift by one frame"))->Enable(continuous && context->TimecodesLoaded());
menu.Append(MENU_SPLIT_BY_KARAOKE,_("Split (by karaoke)"),_("Uses karaoke timing to split line into multiple smaller lines"))->Enable(sels > 0);
// Swaps selection
@@ -318,7 +311,7 @@ void SubtitlesGrid::OnKeyDown(wxKeyEvent &event) {
}
// Duplicate and shift
- if (VFR_Output.IsLoaded()) {
+ if (context->TimecodesLoaded()) {
if (Hotkeys.IsPressed(_T("Grid duplicate and shift one frame"))) {
DuplicateLines(n,n2,true);
return;
@@ -518,7 +511,7 @@ void SubtitlesGrid::OnInsertBeforeVideo (wxCommandEvent &event) {
// Create line to add
AssDialogue *def = new AssDialogue;
- int video_ms = VFR_Output.GetTimeAtFrame(VideoContext::Get()->GetFrameN(),true);
+ int video_ms = context->TimeAtFrame(context->GetFrameN(),agi::vfr::START);
def->Start.SetMS(video_ms);
def->End.SetMS(video_ms+OPT_GET("Timing/Default Duration")->GetInt());
def->Style = GetDialogue(n)->Style;
@@ -542,7 +535,7 @@ void SubtitlesGrid::OnInsertAfterVideo (wxCommandEvent &event) {
// Create line to add
AssDialogue *def = new AssDialogue;
- int video_ms = VFR_Output.GetTimeAtFrame(VideoContext::Get()->GetFrameN(),true);
+ int video_ms = context->TimeAtFrame(context->GetFrameN(),agi::vfr::START);
def->Start.SetMS(video_ms);
def->End.SetMS(video_ms+OPT_GET("Timing/Default Duration")->GetInt());
def->Style = GetDialogue(n)->Style;
@@ -819,7 +812,6 @@ void SubtitlesGrid::ClearMaps() {
void SubtitlesGrid::UpdateMaps() {
BeginBatch();
- VideoContext::Get()->curLine = NULL;
line_iter_map.clear();
BaseGrid::ClearMaps();
@@ -1244,9 +1236,9 @@ void SubtitlesGrid::DuplicateLines(int n1,int n2,bool nextFrame) {
// Shift to next frame
if (nextFrame) {
- int posFrame = VFR_Output.GetFrameAtTime(cur->End.GetMS(),false) + 1;
- cur->Start.SetMS(VFR_Output.GetTimeAtFrame(posFrame,true));
- cur->End.SetMS(VFR_Output.GetTimeAtFrame(posFrame,false));
+ int posFrame = context->FrameAtTime(cur->End.GetMS(),agi::vfr::END) + 1;
+ cur->Start.SetMS(context->TimeAtFrame(posFrame,agi::vfr::START));
+ cur->End.SetMS(context->TimeAtFrame(posFrame,agi::vfr::END));
}
// Insert
@@ -1292,8 +1284,8 @@ void SubtitlesGrid::ShiftLineByTime(int n,int len,int type) {
void SubtitlesGrid::ShiftLineByFrames(int n,int len,int type) {
AssDialogue *cur = GetDialogue(n);
- if (type != 2) cur->Start.SetMS(VFR_Output.GetTimeAtFrame(len + VFR_Output.GetFrameAtTime(cur->Start.GetMS(),true),true));
- if (type != 1) cur->End.SetMS(VFR_Output.GetTimeAtFrame(len + VFR_Output.GetFrameAtTime(cur->End.GetMS(),false),false));
+ if (type != 2) cur->Start.SetMS(context->TimeAtFrame(len + context->FrameAtTime(cur->Start.GetMS(),agi::vfr::START),agi::vfr::START));
+ if (type != 1) cur->End.SetMS(context->TimeAtFrame(len + context->FrameAtTime(cur->End.GetMS(),agi::vfr::END),agi::vfr::END));
}
@@ -1394,19 +1386,19 @@ bool SubtitlesGrid::SplitLineByKaraoke(int lineNumber) {
/// @param videoOnly
///
void SubtitlesGrid::CommitChanges(bool force,bool videoOnly) {
- if (VideoContext::Get()->IsLoaded() || force) {
+ if (context->IsLoaded() || force) {
// Check if it's playing
bool playing = false;
- if (VideoContext::Get()->IsPlaying()) {
+ if (context->IsPlaying()) {
playing = true;
- VideoContext::Get()->Stop();
+ context->Stop();
}
// Update video
- if (VideoContext::Get()->IsLoaded()) VideoContext::Get()->Refresh();
+ if (context->IsLoaded()) context->Refresh();
// Resume play
- if (playing) VideoContext::Get()->Play();
+ if (playing) context->Play();
}
if (!videoOnly) {
@@ -1422,18 +1414,15 @@ void SubtitlesGrid::CommitChanges(bool force,bool videoOnly) {
}
}
-
-
/// @brief Set start to video pos
/// @param start
/// @return
///
void SubtitlesGrid::SetSubsToVideo(bool start) {
- // Check if it's OK to do it
- if (!VFR_Output.IsLoaded()) return;
+ if (!context->IsLoaded()) return;
// Get new time
- int ms = VFR_Output.GetTimeAtFrame(VideoContext::Get()->GetFrameN(),start);
+ int ms = context->TimeAtFrame(context->GetFrameN(),start ? agi::vfr::START : agi::vfr::END);
// Update selection
wxArrayInt sel = GetSelection();
@@ -1468,9 +1457,9 @@ void SubtitlesGrid::SetVideoToSubs(bool start) {
AssDialogue *cur = GetDialogue(sel[0]);
if (cur) {
if (start)
- VideoContext::Get()->JumpToTime(cur->Start.GetMS());
+ context->JumpToTime(cur->Start.GetMS());
else
- VideoContext::Get()->JumpToFrame(VFR_Output.GetFrameAtTime(cur->End.GetMS(),false));
+ context->JumpToTime(cur->End.GetMS(), agi::vfr::END);
}
}
diff --git a/aegisub/src/subs_grid.h b/aegisub/src/subs_grid.h
index 5c8b27c41..adc94c4de 100644
--- a/aegisub/src/subs_grid.h
+++ b/aegisub/src/subs_grid.h
@@ -34,11 +34,6 @@
/// @ingroup main_ui
///
-
-
-
-////////////
-// Includes
#ifndef AGI_PRE
#include
#include
@@ -54,9 +49,6 @@
#include "audio_provider_manager.h"
#include "base_grid.h"
-
-//////////////
-// Prototypes
class AssFile;
class AssEntry;
class AssDialogue;
@@ -64,13 +56,9 @@ class SubsEditBox;
class FrameMain;
class AudioDisplay;
-
-
/// DOCME
typedef std::list::iterator entryIter;
-
-
/// DOCME
/// @class SubtitlesGrid
/// @brief DOCME
diff --git a/aegisub/src/subtitle_format.cpp b/aegisub/src/subtitle_format.cpp
index 2aca78da6..b0b0c8259 100644
--- a/aegisub/src/subtitle_format.cpp
+++ b/aegisub/src/subtitle_format.cpp
@@ -34,9 +34,6 @@
/// @ingroup subtitle_io
///
-
-///////////
-// Headers
#include "config.h"
#ifndef AGI_PRE
@@ -55,8 +52,7 @@
#include "subtitle_format_transtation.h"
#include "subtitle_format_ttxt.h"
#include "subtitle_format_txt.h"
-#include "vfr.h"
-
+#include "video_context.h"
/// @brief Constructor
///
@@ -66,24 +62,18 @@ SubtitleFormat::SubtitleFormat() {
isCopy = false;
}
-
-
/// @brief Destructor
///
SubtitleFormat::~SubtitleFormat () {
Remove();
}
-
-
/// DOCME
std::list SubtitleFormat::formats;
/// DOCME
bool SubtitleFormat::loaded = false;
-
-
/// @brief Set target
/// @param file
///
@@ -94,8 +84,6 @@ void SubtitleFormat::SetTarget(AssFile *file) {
assFile = file;
}
-
-
/// @brief Create copy
///
void SubtitleFormat::CreateCopy() {
@@ -103,8 +91,6 @@ void SubtitleFormat::CreateCopy() {
isCopy = true;
}
-
-
/// @brief Clear copy
///
void SubtitleFormat::ClearCopy() {
@@ -115,16 +101,12 @@ void SubtitleFormat::ClearCopy() {
}
}
-
-
/// @brief Clear subtitles
///
void SubtitleFormat::Clear() {
assFile->Clear();
}
-
-
/// @brief Load default
/// @param defline
///
@@ -132,8 +114,6 @@ void SubtitleFormat::LoadDefault(bool defline) {
assFile->LoadDefault(defline);
}
-
-
/// @brief Add line
/// @param data
/// @param group
@@ -143,8 +123,6 @@ void SubtitleFormat::AddLine(wxString data,wxString group,int &version,wxString
assFile->AddLine(data,group,version,outgroup);
}
-
-
/// @brief Add formats
///
void SubtitleFormat::LoadFormats () {
@@ -164,8 +142,6 @@ void SubtitleFormat::LoadFormats () {
loaded = true;
}
-
-
/// @brief Destroy formats
///
void SubtitleFormat::DestroyFormats () {
@@ -176,8 +152,6 @@ void SubtitleFormat::DestroyFormats () {
formats.clear();
}
-
-
/// @brief Get an appropriate reader
/// @param filename
/// @return
@@ -193,8 +167,6 @@ SubtitleFormat *SubtitleFormat::GetReader(wxString filename) {
return NULL;
}
-
-
/// @brief Get an appropriate writer
/// @param filename
/// @return
@@ -210,8 +182,6 @@ SubtitleFormat *SubtitleFormat::GetWriter(wxString filename) {
return NULL;
}
-
-
/// @brief Register
/// @return
///
@@ -223,8 +193,6 @@ void SubtitleFormat::Register() {
formats.push_back(this);
}
-
-
/// @brief Remove
/// @return
///
@@ -238,8 +206,6 @@ void SubtitleFormat::Remove() {
}
}
-
-
/// @brief Get read wildcards
/// @return
///
@@ -247,8 +213,6 @@ wxArrayString SubtitleFormat::GetReadWildcards() {
return wxArrayString();
}
-
-
/// @brief Get write wildcards
/// @return
///
@@ -256,8 +220,6 @@ wxArrayString SubtitleFormat::GetWriteWildcards() {
return wxArrayString();
}
-
-
/// @brief Get wildcard list
/// @param mode
/// @return
@@ -313,8 +275,6 @@ wxString SubtitleFormat::GetWildcards(int mode) {
return final;
}
-
-
/// @brief Ask the user to enter the FPS
/// @param showSMPTE
/// @return
@@ -325,11 +285,12 @@ SubtitleFormat::FPSRational SubtitleFormat::AskForFPS(bool showSMPTE) {
fps_rat.smpte_dropframe = false; // ensure it's false by default
// Video FPS
- bool vidLoaded = VFR_Output.IsLoaded();
+ VideoContext *context = VideoContext::Get();
+ bool vidLoaded = context->TimecodesLoaded();
if (vidLoaded) {
wxString vidFPS;
- if (VFR_Output.GetFrameRateType() == VFR) vidFPS = _T("VFR");
- else vidFPS = wxString::Format(_T("%.3f"),VFR_Output.GetAverage());
+ if (context->FPS().IsVFR()) vidFPS = _T("VFR");
+ else vidFPS = wxString::Format(_T("%.3f"),context->FPS().FPS());
choices.Add(wxString::Format(_T("From video (%s)"),vidFPS.c_str()));
}
@@ -403,16 +364,12 @@ SubtitleFormat::FPSRational SubtitleFormat::AskForFPS(bool showSMPTE) {
return fps_rat;
}
-
-
/// @brief Sort lines
///
void SubtitleFormat::SortLines() {
AssFile::Sort(*Line);
}
-
-
/// @brief Convert tags
/// @param format
/// @param lineEnd
@@ -438,8 +395,6 @@ void SubtitleFormat::ConvertTags(int format,const wxString &lineEnd,bool mergeLi
}
}
-
-
/// @brief Remove all comment lines
///
void SubtitleFormat::StripComments() {
@@ -458,8 +413,6 @@ void SubtitleFormat::StripComments() {
}
}
-
-
/// @brief Remove all non-dialogue lines
///
void SubtitleFormat::StripNonDialogue() {
@@ -477,8 +430,6 @@ void SubtitleFormat::StripNonDialogue() {
}
}
-
-
/// @brief Helper function for RecombineOverlaps()
/// @param list
/// @param next
@@ -501,7 +452,6 @@ static void InsertLineSortedIntoList(std::list &list, std::list
@@ -49,22 +45,15 @@
#include
-
-//////////////
-// Prototypes
class AssFile;
class AssEntry;
-
-
/// DOCME
/// @class SubtitleFormat
/// @brief DOCME
///
/// DOCME
class SubtitleFormat {
-private:
-
/// DOCME
bool isCopy;
@@ -74,7 +63,6 @@ private:
void Register();
void Remove();
-
/// DOCME
static std::list formats;
@@ -82,7 +70,6 @@ private:
static bool loaded;
protected:
-
/// DOCME
struct FPSRational {
@@ -96,7 +83,6 @@ protected:
bool smpte_dropframe;
};
-
/// DOCME
std::list *Line;
@@ -131,7 +117,6 @@ public:
static wxString GetWildcards(int mode);
-
/// @brief DOCME
/// @param filename
/// @return
@@ -162,6 +147,4 @@ public:
static void DestroyFormats();
};
-
DEFINE_SIMPLE_EXCEPTION(SubtitleFormatParseError, agi::InvalidInputException, "subtitle_io/parse/generic")
-
diff --git a/aegisub/src/subtitle_format_microdvd.cpp b/aegisub/src/subtitle_format_microdvd.cpp
index 98c585304..e62f28373 100644
--- a/aegisub/src/subtitle_format_microdvd.cpp
+++ b/aegisub/src/subtitle_format_microdvd.cpp
@@ -34,9 +34,6 @@
/// @ingroup subtitle_io
///
-
-///////////
-// Headers
#include "config.h"
#ifndef AGI_PRE
@@ -48,42 +45,22 @@
#include "subtitle_format_microdvd.h"
#include "text_file_reader.h"
#include "text_file_writer.h"
-#include "vfr.h"
+#include "video_context.h"
-
-/// @brief Get format name
-/// @return
-///
wxString MicroDVDSubtitleFormat::GetName() {
return _T("MicroDVD");
}
-
-
-/// @brief Get read wildcards
-/// @return
-///
wxArrayString MicroDVDSubtitleFormat::GetReadWildcards() {
wxArrayString formats;
formats.Add(_T("sub"));
return formats;
}
-
-
-/// @brief Get write wildcards
-/// @return
-///
wxArrayString MicroDVDSubtitleFormat::GetWriteWildcards() {
return GetReadWildcards();
}
-
-
-/// @brief Can read a file?
-/// @param filename
-/// @return
-///
bool MicroDVDSubtitleFormat::CanReadFile(wxString filename) {
// Return false immediately if extension is wrong
if (filename.Right(4).Lower() != _T(".sub")) return false;
@@ -98,43 +75,25 @@ bool MicroDVDSubtitleFormat::CanReadFile(wxString filename) {
return false;
}
-
-
-/// @brief Can write a file?
-/// @param filename
-/// @return
-///
bool MicroDVDSubtitleFormat::CanWriteFile(wxString filename) {
return (filename.Right(4).Lower() == _T(".sub"));
}
-
-
-/// @brief Read a file
-/// @param filename
-/// @param forceEncoding
-/// @return
-///
void MicroDVDSubtitleFormat::ReadFile(wxString filename,wxString forceEncoding) {
- // Load and prepare regexp
TextFileReader file(filename);
wxRegEx exp(_T("^[\\{\\[]([0-9]+)[\\}\\]][\\{\\[]([0-9]+)[\\}\\]](.*)$"),wxRE_ADVANCED);
- // Load default
LoadDefault(false);
- // Prepare conversion
- FrameRate cfr;
- FrameRate *rate = 𝔠
+ agi::vfr::Framerate cfr;
+ const agi::vfr::Framerate *rate = 𝔠
- // Loop
bool isFirst = true;
FPSRational fps_rat;
double fps = 0.0;
while (file.HasMoreLines()) {
wxString line = file.ReadLineFromFile();
if (exp.Matches(line)) {
- // Parse
long f1,f2;
exp.GetMatch(line,1).ToLong(&f1);
exp.GetMatch(line,2).ToLong(&f2);
@@ -147,7 +106,7 @@ void MicroDVDSubtitleFormat::ReadFile(wxString filename,wxString forceEncoding)
try {
text.ToDouble(&fps);
}
- catch (...) {}
+ catch (...) { }
}
isFirst = false;
@@ -155,24 +114,22 @@ void MicroDVDSubtitleFormat::ReadFile(wxString filename,wxString forceEncoding)
if (fps <= 0.0) {
fps_rat = AskForFPS();
if (fps_rat.num == 0) return;
- else if (fps_rat.num > 0) cfr.SetCFR(double(fps_rat.num)/double(fps_rat.den));
- else rate = &VFR_Output;
+ else if (fps_rat.num > 0) cfr = double(fps_rat.num)/fps_rat.den;
+ else rate = &VideoContext::Get()->FPS();
}
else {
- cfr.SetCFR(fps);
+ cfr = fps;
continue;
}
}
// Start and end times
int start,end;
- start = rate->GetTimeAtFrame(f1,true);
- end = rate->GetTimeAtFrame(f2,false);
+ start = rate->TimeAtFrame(f1,agi::vfr::START);
+ end = rate->TimeAtFrame(f2,agi::vfr::END);
- // Process text
text.Replace(_T("|"),_T("\\N"));
- // Create and insert line
AssDialogue *line = new AssDialogue();
line->group = _T("[Events]");
line->Style = _T("Default");
@@ -184,21 +141,15 @@ void MicroDVDSubtitleFormat::ReadFile(wxString filename,wxString forceEncoding)
}
}
-
-
-/// @brief Write a file
-/// @param filename
-/// @param encoding
-///
void MicroDVDSubtitleFormat::WriteFile(wxString filename,wxString encoding) {
- // Set FPS
- FrameRate cfr;
- FrameRate *rate = 𝔠
+ agi::vfr::Framerate cfr;
+ const agi::vfr::Framerate *rate = 𝔠
+
FPSRational fps_rat = AskForFPS();
if (fps_rat.num == 0 || fps_rat.den == 0) return;
- double fps = double(fps_rat.num) / double(fps_rat.den);
- if (fps > 0.0) cfr.SetCFR(fps);
- else rate = &VFR_Output;
+ double fps = double(fps_rat.num) / fps_rat.den;
+ if (fps > 0.0) cfr = fps;
+ else rate = &VideoContext::Get()->FPS();
// Convert file
CreateCopy();
@@ -208,12 +159,11 @@ void MicroDVDSubtitleFormat::WriteFile(wxString filename,wxString encoding) {
MergeIdentical();
ConvertTags(1,_T("|"));
- // Open file
TextFileWriter file(filename,encoding);
// Write FPS line
- if (rate->GetFrameRateType() != VFR) {
- file.WriteLineToFile(wxString::Format(_T("{1}{1}%.6f"),rate->GetAverage()));
+ if (!rate->IsVFR()) {
+ file.WriteLineToFile(wxString::Format(_T("{1}{1}%.6f"),rate->FPS()));
}
// Write lines
@@ -221,17 +171,12 @@ void MicroDVDSubtitleFormat::WriteFile(wxString filename,wxString encoding) {
for (list::iterator cur=Line->begin();cur!=Line->end();cur++) {
AssDialogue *current = dynamic_cast(*cur);
if (current && !current->Comment) {
- // Prepare data
- int start = rate->GetFrameAtTime(current->Start.GetMS(),true);
- int end = rate->GetFrameAtTime(current->End.GetMS(),false);
+ int start = rate->FrameAtTime(current->Start.GetMS(),agi::vfr::START);
+ int end = rate->FrameAtTime(current->End.GetMS(),agi::vfr::END);
- // Write data
file.WriteLineToFile(wxString::Format(_T("{%i}{%i}%s"),start,end,current->Text.c_str()));
}
}
- // Clean up
ClearCopy();
}
-
-
diff --git a/aegisub/src/subtitle_format_microdvd.h b/aegisub/src/subtitle_format_microdvd.h
index 4da8eeea6..5bf20b36a 100644
--- a/aegisub/src/subtitle_format_microdvd.h
+++ b/aegisub/src/subtitle_format_microdvd.h
@@ -34,14 +34,8 @@
/// @ingroup subtitle_io
///
-
-
-
-///////////
-// Headers
#include "subtitle_format.h"
-
/// DOCME
/// @class MicroDVDSubtitleFormat
/// @brief DOCME
@@ -59,5 +53,3 @@ public:
bool CanWriteFile(wxString filename);
void WriteFile(wxString filename,wxString encoding);
};
-
-
diff --git a/aegisub/src/subtitles_provider_csri.cpp b/aegisub/src/subtitles_provider_csri.cpp
index 433451dab..16aa654a3 100644
--- a/aegisub/src/subtitles_provider_csri.cpp
+++ b/aegisub/src/subtitles_provider_csri.cpp
@@ -47,7 +47,6 @@
#include "text_file_writer.h"
#include "video_context.h"
-
/// @brief Constructor
/// @param type
///
@@ -56,17 +55,14 @@ CSRISubtitlesProvider::CSRISubtitlesProvider(wxString type) {
instance = NULL;
}
-
-
/// @brief Destructor
///
CSRISubtitlesProvider::~CSRISubtitlesProvider() {
+ if (!tempfile.empty()) wxRemoveFile(tempfile);
if (instance) csri_close(instance);
instance = NULL;
}
-
-
/// @brief Load subtitles
/// @param subs
///
@@ -108,14 +104,16 @@ void CSRISubtitlesProvider::LoadSubtitles(AssFile *subs) {
// Open from disk
else {
- wxString subsFileName = VideoContext::Get()->GetTempWorkFile();
- subs->Save(subsFileName,false,false,wxSTRING_ENCODING);
- instance = csri_open_file(renderer,subsFileName.mb_str(wxConvUTF8),NULL);
+ if (tempfile.empty()) {
+ tempfile = wxFileName::CreateTempFileName(_T("aegisub"));
+ wxRemoveFile(tempfile);
+ tempfile += L".ass";
+ }
+ subs->Save(tempfile,false,false,wxSTRING_ENCODING);
+ instance = csri_open_file(renderer,tempfile.utf8_str(),NULL);
}
}
-
-
/// @brief Draw subtitles
/// @param dst
/// @param time
@@ -155,8 +153,6 @@ void CSRISubtitlesProvider::DrawSubtitles(AegiVideoFrame &dst,double time) {
csri_render(instance,&frame,time);
}
-
-
/// @brief Get CSRI subtypes
///
wxArrayString CSRISubtitlesProviderFactory::GetSubTypes() {
@@ -179,7 +175,4 @@ wxArrayString CSRISubtitlesProviderFactory::GetSubTypes() {
return final;
}
-
#endif // WITH_CSRI
-
-
diff --git a/aegisub/src/subtitles_provider_csri.h b/aegisub/src/subtitles_provider_csri.h
index 4577a0d40..ddc954bd9 100644
--- a/aegisub/src/subtitles_provider_csri.h
+++ b/aegisub/src/subtitles_provider_csri.h
@@ -34,15 +34,10 @@
/// @ingroup subtitle_rendering
///
-
-///////////
-// Headers
-
#ifdef WITH_CSRI
#include "include/aegisub/subtitles_provider.h"
#ifdef WIN32
-
/// DOCME
#define CSRIAPI
#endif
@@ -53,21 +48,19 @@
#include
#endif
-
/// DOCME
/// @class CSRISubtitlesProvider
/// @brief DOCME
///
/// DOCME
class CSRISubtitlesProvider : public SubtitlesProvider {
-private:
-
/// DOCME
wxString subType;
/// DOCME
csri_inst *instance;
+ wxString tempfile;
public:
CSRISubtitlesProvider(wxString subType);
~CSRISubtitlesProvider();
@@ -76,8 +69,6 @@ public:
void DrawSubtitles(AegiVideoFrame &dst,double time);
};
-
-
/// DOCME
/// @class CSRISubtitlesProviderFactory
/// @brief DOCME
@@ -85,7 +76,6 @@ public:
/// DOCME
class CSRISubtitlesProviderFactory : public SubtitlesProviderFactory {
public:
-
/// @brief DOCME
/// @param subType
///
@@ -94,5 +84,3 @@ public:
};
#endif
-
-
diff --git a/aegisub/src/timeedit_ctrl.cpp b/aegisub/src/timeedit_ctrl.cpp
index e1b9e13b7..203b574fd 100644
--- a/aegisub/src/timeedit_ctrl.cpp
+++ b/aegisub/src/timeedit_ctrl.cpp
@@ -34,9 +34,6 @@
/// @ingroup custom_control
///
-
-////////////
-// Includes
#include "config.h"
#ifndef AGI_PRE
@@ -51,8 +48,7 @@
#include "main.h"
#include "options.h"
#include "timeedit_ctrl.h"
-#include "vfr.h"
-
+#include "video_context.h"
#ifdef __WXGTK__
/// Use the multiline style only on wxGTK to workaround some wxGTK bugs with the default singleline style.
@@ -63,7 +59,6 @@
#define TimeEditWindowStyle wxTE_CENTRE
#endif
-
/// @brief Constructor
/// @param parent
/// @param id
@@ -114,9 +109,6 @@ wxTextCtrl(parent,id,value,pos,size,TimeEditWindowStyle | style,validator,name)
Connect(wxEVT_KILL_FOCUS,wxFocusEventHandler(TimeEdit::OnKillFocus));
}
-
-///////////////
-// Event table
BEGIN_EVENT_TABLE(TimeEdit, wxTextCtrl)
EVT_MOUSE_EVENTS(TimeEdit::OnMouseEvent)
EVT_KEY_DOWN(TimeEdit::OnKeyDown)
@@ -124,30 +116,20 @@ BEGIN_EVENT_TABLE(TimeEdit, wxTextCtrl)
EVT_MENU(Time_Edit_Paste,TimeEdit::OnPaste)
END_EVENT_TABLE()
-
-
/// @brief Modified event
/// @param event
-/// @return
-///
void TimeEdit::OnModified(wxCommandEvent &event) {
event.Skip();
if (!ready) return;
Modified();
}
-
-
/// @brief Modified function
/// @param byUser
-/// @return
-///
void TimeEdit::Modified(bool byUser) {
- // Lock
if (!ready) return;
ready = false;
- // Update
if (byFrame) Update();
else UpdateTime(byUser);
@@ -156,13 +138,9 @@ void TimeEdit::Modified(bool byUser) {
SetBackgroundColour(lagi_wxColour(OPT_GET("Colour/Background/Modified")->GetColour()));
}
modified = true;
-
- // Done
ready = true;
}
-
-
/// @brief Set time and update stuff
/// @param ms
/// @param setModified
@@ -174,18 +152,14 @@ void TimeEdit::SetTime(int ms,bool setModified) {
if (setModified && oldMs != ms) Modified(false);
}
-
-
/// @brief Toggles between set by frame and time
/// @param enable
-/// @return
-///
void TimeEdit::SetByFrame(bool enable) {
if (enable == byFrame) return;
// By frames
if (enable) {
- if (VFR_Output.IsLoaded()) {
+ if (VideoContext::Get()->IsLoaded()) {
byFrame = true;
UpdateText();
}
@@ -198,22 +172,18 @@ void TimeEdit::SetByFrame(bool enable) {
}
}
-
-
/// @brief Update text to reflect time value
///
void TimeEdit::UpdateText() {
ready = false;
if (byFrame) {
- int frame_n = VFR_Output.GetFrameAtTime(time.GetMS(),!isEnd);
+ int frame_n = VideoContext::Get()->FrameAtTime(time.GetMS(),isEnd ? agi::vfr::END : agi::vfr::START);
SetValue(wxString::Format(_T("%i"),frame_n));
}
else SetValue(time.GetASSFormated());
ready = true;
}
-
-
/// @brief Update
///
void TimeEdit::Update() {
@@ -221,7 +191,7 @@ void TimeEdit::Update() {
if (byFrame) {
long temp;
GetValue().ToLong(&temp);
- time.SetMS(VFR_Output.GetTimeAtFrame(temp,!isEnd));
+ time.SetMS(VideoContext::Get()->TimeAtFrame(temp,isEnd ? agi::vfr::END : agi::vfr::START));
}
// Update time if not on insertion mode
@@ -238,8 +208,6 @@ void TimeEdit::Update() {
modified = false;
}
-
-
/// @brief Reads value from a text control and update it
/// @param byUser
///
@@ -273,8 +241,6 @@ void TimeEdit::UpdateTime(bool byUser) {
}
}
-
-
/// @brief Key pressed
/// @param event
///
@@ -316,8 +282,6 @@ void TimeEdit::OnKeyDown(wxKeyEvent &event) {
}
}
-
-
/// @brief Focus lost
/// @param event
///
@@ -331,14 +295,10 @@ void TimeEdit::OnKillFocus(wxFocusEvent &event) {
event.Skip();
}
-
///// Mouse/copy/paste events down here /////
-
/// @brief Mouse event
/// @param event
-/// @return
-///
void TimeEdit::OnMouseEvent(wxMouseEvent &event) {
// Right click context menu
if (event.RightUp()) {
@@ -355,8 +315,6 @@ void TimeEdit::OnMouseEvent(wxMouseEvent &event) {
event.Skip();
}
-
-
/// @brief Menu Copy
/// @param event
///
@@ -367,8 +325,6 @@ void TimeEdit::OnCopy(wxCommandEvent &event) {
Refresh();
}
-
-
/// @brief Menu Paste
/// @param event
///
@@ -378,10 +334,7 @@ void TimeEdit::OnPaste(wxCommandEvent &event) {
Refresh();
}
-
-
/// @brief Copy to clipboard
-/// @return
///
void TimeEdit::CopyTime() {
// Frame
@@ -397,8 +350,6 @@ void TimeEdit::CopyTime() {
}
}
-
-
/// @brief Paste from clipboard
///
void TimeEdit::PasteTime() {
@@ -432,5 +383,3 @@ void TimeEdit::PasteTime() {
}
}
}
-
-
diff --git a/aegisub/src/vfr.cpp b/aegisub/src/vfr.cpp
deleted file mode 100644
index f128c99e0..000000000
--- a/aegisub/src/vfr.cpp
+++ /dev/null
@@ -1,393 +0,0 @@
-// Copyright (c) 2005-2006, Rodrigo Braz Monteiro, Fredrik Mellbin
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-// * Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution.
-// * Neither the name of the Aegisub Group nor the names of its contributors
-// may be used to endorse or promote products derived from this software
-// without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-// POSSIBILITY OF SUCH DAMAGE.
-//
-// Aegisub Project http://www.aegisub.org/
-//
-// $Id$
-
-/// @file vfr.cpp
-/// @brief Handle variable frame rate files
-/// @ingroup video_input
-///
-
-#include "config.h"
-
-#ifndef AGI_PRE
-#include
-#endif
-
-#include "compat.h"
-#include "main.h"
-#include "options.h"
-#include "text_file_reader.h"
-#include "text_file_writer.h"
-#include "utils.h"
-#include "vfr.h"
-
-
-/// @brief V2 Clear function
-void FrameRate::Clear () {
- Frame.clear();
-}
-
-/// @brief V2 Add frame
-/// @param ms
-void FrameRate::AddFrame(int ms) {
- Frame.push_back(ms);
-}
-
-/// @brief V2 Get Average
-void FrameRate::CalcAverage() {
- if (Frame.size() <= 1)
- throw _("No timecodes to average");
-
- AverageFrameRate = double(Frame.back()) / (Frame.size()-1);
-}
-
-/// @brief Constructor
-FrameRate::FrameRate() {
- Unload();
-}
-
-/// @brief Destructor
-FrameRate::~FrameRate() {
- Unload();
-}
-
-/// @brief Loads VFR file
-/// @param filename
-void FrameRate::Load(wxString filename) {
- using namespace std;
-
- Unload();
-
- // Check if file exists
- wxFileName filetest(filename);
- if (!filetest.FileExists()) throw _T("File not found.");
-
- // Open file
- TextFileReader file(filename);
-
- try {
- // Read header
- wxString curLine;
- curLine = file.ReadLineFromFile();
- wxString header = curLine;
- bool first = (header.Left(7).Lower() == _T("assume "));
-
- // V1, code converted from avcvfr9
- if (header == _T("# timecode format v1") || first) {
- // Locate the default fps line
- do {
- // Get next line
- if (!first) curLine = file.ReadLineFromFile();
- first = false;
-
- // Skip empty lines and comments
- if (curLine == _T("") || curLine.Left(1) == _T("#")) continue;
-
- else if (curLine.Left(7).Lower() != _T("assume ")) throw _T("Encountered data before 'Assume ' line");
- else {
- if (!curLine.Mid(6).ToDouble(&AverageFrameRate) || AverageFrameRate <= 0) throw _T("Invalid 'Assume ' line");
- break;
- }
- } while (file.HasMoreLines());
-
- // Read and expand all timecodes to v2
- wxString curline;
-
- double currenttime = 0;
- int lposition = -1;
-
- long lstart;
- long lend;
- double lfps;
-
- while (file.HasMoreLines()) {
- curLine = file.ReadLineFromFile();
-
- // 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");
-
- if (lstart <= lposition)
- throw _T("Timecode parsing error, out of order or overlapping timecode range found");
-
-
- for (int i = 0; i <= lstart - lposition - 2; i++)
- AddFrame((int)(floor(currenttime+(i*1000) / AverageFrameRate)));
-
- currenttime += ((lstart - lposition - 1)*1000) / AverageFrameRate;
-
- for (int i = 0; i <= lend - lstart; i++)
- AddFrame((int)(floor(currenttime+(i*1000) / lfps)));
-
- currenttime += ((lend - lstart + 1)*1000) / lfps;
-
- lposition = lend;
- }
-
- AddFrame(currenttime);
- last_time = currenttime;
- last_frame = (int)Frame.size() - 1;
- }
-
- // 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.HasMoreLines()) {
- curLine = file.ReadLineFromFile();
-
- //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 = (int)Frame.size() - 1;
-
- CalcAverage();
-
- }
-
- // Unknown
- else {
- throw _T("Unknown time code file format.");
- }
-
- }
- catch (...) {
- Unload();
- throw;
- }
-
- // Close file
- loaded = true;
- vfrFile = filename;
- FrameRateType = VFR;
-
- // Add to recent
- config::mru->Add("Timecodes", STD_STR(filename));
-}
-
-/// @brief Save
-/// @param filename
-void FrameRate::Save(wxString filename) {
- TextFileWriter file(filename,_T("ASCII"));
- file.WriteLineToFile(_T("# timecode format v2"));
- for (size_t i=0;i newTimes) {
- Unload();
-
- loaded = true;
- FrameRateType = VFR;
-
- // Set new VFR;
- Frame = newTimes;
- CalcAverage();
- last_time = newTimes.back();
- last_frame = (int)newTimes.size();
-}
-
-/// @brief Gets frame number at time
-/// @param ms
-/// @param start
-/// @return
-int FrameRate::PFrameAtTime(int ms,bool start) const {
- if (!loaded) return -1;
-
- // Lines begin on the first frame whose start time is greater than or equal
- // to the line's start time, and are last visible on the last frame whose
- // start time is less than (note: not equal) the line's end time
-
- if (FrameRateType == CFR || Frame.size() == 0 || ms < 0) {
- double value = double(ms) * AverageFrameRate / 1000.;
- if (start) return (int)ceil(value);
- else return (int)floor(value - .0001);
- }
- else if (FrameRateType == VFR) {
- // Inside VFR range
- if (ms <= Frame.back()) {
- int frame = std::distance(Frame.begin(), std::lower_bound(Frame.begin(), Frame.end(), ms));
- if (!start && frame > 0) {
- // In the end case, frame is the first frame in which the line
- // is no longer visible, so subtract 1
-
- // Don't need to worry about the equal case here as lower_bound
- // finds the entry >= ms
-
- // The frame > 0 check isn't actually correct -- the frame
- // ending at time 0 should be -1, but parts of the program
- // (like PTimeAtFrame below) assume that frames are positive
- --frame;
- }
- return frame;
- }
- // After VFR range
- else {
- if (start) return (int)(last_frame + ceil((ms-last_time) * AverageFrameRate / 1000.));
- else return (int)(last_frame + floor((ms-last_time - .0001) * AverageFrameRate / 1000.));
- }
- }
- return -1;
-}
-
-/// @brief Gets time at frame
-/// @param frame
-/// @return
-int FrameRate::PTimeAtFrame(int frame) const {
- // Not loaded
- if (!loaded) return -1;
-
- // For negative/zero times, fallback to zero
- if (frame <= 0) return 0;
-
- // Constant frame rate
- if (FrameRateType == CFR || Frame.size() == 0) {
- return (int)floor(double(frame) / AverageFrameRate * 1000.0);
- }
-
- // Variable frame rate
- else if (FrameRateType == VFR) {
- // Is it inside frame rate range? If so, just get the value from timecodes table
- if (frame < (signed) Frame.size()) return Frame.at(frame);
-
- // Otherwise, calculate it
- else return (int)floor(Frame.back() + double(frame-Frame.size()+1) / AverageFrameRate * 1000.0);
- }
-
- // Unknown frame rate type
- return -1;
-}
-
-/// @brief otherwise for start frames returns the adjusted time for end frames when start=false Get correct frame at time
-/// @param ms
-/// @param start
-/// @return
-int FrameRate::GetFrameAtTime(int ms,bool start) const {
- return PFrameAtTime(ms,start);
-}
-
-/// @brief compensates and returns an end time when start=false Get correct time at frame
-/// @param frame Frame number
-/// @param start Adjust for start time
-/// @param exact Don't do awful things to avoid rounding errors
-/// @return
-int FrameRate::GetTimeAtFrame(int frame,bool start,bool exact) const {
- int finalTime;
-
- // Exact, for display
- if (exact) {
- finalTime = PTimeAtFrame(frame);
- }
-
- // Adjusted, for subs sync
- else {
- if (start) {
- finalTime = (PTimeAtFrame(frame-1) + PTimeAtFrame(frame))/2;
- }
- else {
- //if (FrameRateType == VFR) finalTime = PTimeAtFrame(frame);
- //else finalTime = (PTimeAtFrame(frame) + PTimeAtFrame(frame+1))/2;
- finalTime = (PTimeAtFrame(frame) + PTimeAtFrame(frame+1))/2;
- }
- }
-
- return finalTime;
-}
-
-/// @brief Get the current list of frames/times
-/// @return
-std::vector FrameRate::GetFrameTimeList() const {
- return Frame;
-}
-
-bool FrameRate::operator==(FrameRate const& rgt) {
- if (FrameRateType != rgt.FrameRateType) return false;
- if (FrameRateType == NONE) return true;
- if (FrameRateType == CFR) return AverageFrameRate == rgt.AverageFrameRate;
- return Frame == rgt.Frame;
-}
-
-/// DOCME
-FrameRate VFR_Output;
-
-/// DOCME
-FrameRate VFR_Input;
diff --git a/aegisub/src/vfr.h b/aegisub/src/vfr.h
deleted file mode 100644
index 5b4a09757..000000000
--- a/aegisub/src/vfr.h
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright (c) 2005-2006, Rodrigo Braz Monteiro, Fredrik Mellbin
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-// * Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution.
-// * Neither the name of the Aegisub Group nor the names of its contributors
-// may be used to endorse or promote products derived from this software
-// without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-// POSSIBILITY OF SUCH DAMAGE.
-//
-// Aegisub Project http://www.aegisub.org/
-//
-// $Id$
-
-/// @file vfr.h
-/// @see vfr.cpp
-/// @ingroup video_input
-///
-
-// 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
-
-
-#ifndef AGI_PRE
-#include
-#include
-
-#include
-#include
-#endif
-
-/// DOCME
-enum ASS_FrameRateType {
- NONE,
- CFR,
- VFR
-};
-
-
-/// DOCME
-/// @class FrameRate
-/// @brief DOCME
-///
-/// DOCME
-class FrameRate {
- friend class VideoContext;
-
-private:
-
- /// DOCME
- double last_time;
-
- /// DOCME
- int last_frame;
-
- /// DOCME
- std::vector Frame;
-
-
- /// DOCME
- double AverageFrameRate;
-
- void AddFrame(int ms);
- void Clear();
-
- void CalcAverage();
- int PFrameAtTime(int ms,bool useCeil=false) const;
- int PTimeAtFrame(int frame) const;
-
-
- /// DOCME
- ASS_FrameRateType FrameRateType;
-
- /// DOCME
- bool loaded;
-
- /// DOCME
- wxString vfrFile;
-
-public:
- FrameRate();
- ~FrameRate();
-
- void SetCFR(double fps);
- void SetVFR(std::vector times);
-
- // Loading always unloads even on failure
- void Load(wxString file);
- void Save(wxString file);
- void Unload();
-
- int GetFrameAtTime(int ms,bool start=true) const;
- int GetTimeAtFrame(int frame,bool start=true,bool exact=false) const;
-
-
- /// @brief DOCME
- /// @return
- ///
- double GetAverage() const { return AverageFrameRate; };
-
- /// @brief DOCME
- /// @return
- ///
- bool IsLoaded() const { return loaded; };
-
- /// @brief DOCME
- /// @return
- ///
- ASS_FrameRateType GetFrameRateType() const { return FrameRateType; };
-
- /// @brief DOCME
- ///
- wxString GetFilename() const { return vfrFile; };
-
- std::vector GetFrameTimeList() const;
-
- bool operator==(FrameRate const& rgt);
-};
-
-extern FrameRate VFR_Output;
-extern FrameRate VFR_Input;
diff --git a/aegisub/src/video_box.cpp b/aegisub/src/video_box.cpp
index 2b5f8ca92..0cadb9850 100644
--- a/aegisub/src/video_box.cpp
+++ b/aegisub/src/video_box.cpp
@@ -58,7 +58,6 @@
#include "subs_grid.h"
#include "toggle_bitmap.h"
#include "utils.h"
-#include "vfr.h"
#include "video_box.h"
#include "video_context.h"
#include "video_display.h"
diff --git a/aegisub/src/video_context.cpp b/aegisub/src/video_context.cpp
index 28984df66..ddb07704c 100644
--- a/aegisub/src/video_context.cpp
+++ b/aegisub/src/video_context.cpp
@@ -34,9 +34,6 @@
/// @ingroup video
///
-
-////////////
-// Includes
#include "config.h"
#ifndef AGI_PRE
@@ -63,6 +60,8 @@
#include "ass_time.h"
#include "audio_display.h"
#include "compat.h"
+#include "keyframe.h"
+#include
#include "main.h"
#include "mkv_wrap.h"
#include "options.h"
@@ -71,97 +70,64 @@
#include "subs_grid.h"
#include "subtitles_provider_manager.h"
#include "utils.h"
-#include "vfr.h"
#include "video_box.h"
#include "video_context.h"
#include "video_display.h"
#include "video_provider_manager.h"
-
-///////
-// IDs
+/// IDs
enum {
-
- /// DOCME
VIDEO_PLAY_TIMER = 1300
};
-
-///////////////
-// Event table
BEGIN_EVENT_TABLE(VideoContext, wxEvtHandler)
EVT_TIMER(VIDEO_PLAY_TIMER,VideoContext::OnPlayTimer)
END_EVENT_TABLE()
-/// DOCME
-VideoContext *VideoContext::instance = NULL;
-
/// @brief Constructor
///
VideoContext::VideoContext()
: ownGlContext(false)
, glContext(NULL)
-, provider(NULL)
-, subsProvider(NULL)
-, keyFramesLoaded(false)
-, overKeyFramesLoaded(false)
, startFrame(-1)
, endFrame(-1)
, playNextFrame(-1)
, nextFrame(-1)
-, loaded(false)
, isPlaying(false)
, keepAudioSync(true)
-, w(-1)
-, h(-1)
, frame_n(0)
, length(0)
-, fps(0)
, arValue(1.)
, arType(0)
, hasSubtitles(false)
, playAudioOnStep(OPT_GET("Audio/Plays When Stepping Video"))
, grid(NULL)
-, curLine(NULL)
, audio(NULL)
+, VFR_Input(videoFPS)
+, VFR_Output(ovrFPS)
{
}
-/// @brief Destructor
-///
VideoContext::~VideoContext () {
- Reset();
+ if (audio && audio->temporary) {
+ delete audio->provider;
+ delete audio->player;
+ }
+ tempFrame.Clear();
if (ownGlContext)
delete glContext;
- glContext = NULL;
}
-/// @brief Get Instance
-/// @return
-///
VideoContext *VideoContext::Get() {
- if (!instance) {
- instance = new VideoContext;
- }
- return instance;
+ static VideoContext instance;
+ return &instance;
}
-/// @brief Clear
-///
-void VideoContext::Clear() {
- instance->audio = NULL;
- delete instance;
- instance = NULL;
-}
-
-/// @brief Reset
-///
void VideoContext::Reset() {
- loaded = false;
- StandardPaths::SetPathValue(_T("?video"),_T(""));
+ StandardPaths::SetPathValue(_T("?video"), "");
- KeyFrames.Clear();
- keyFramesLoaded = false;
+ keyFrames.clear();
+ videoFPS = agi::vfr::Framerate();
// Remove temporary audio provider
if (audio && audio->temporary) {
@@ -175,133 +141,82 @@ void VideoContext::Reset() {
// Remove video data
frame_n = 0;
length = 0;
- fps = 0;
- keyFramesLoaded = false;
- overKeyFramesLoaded = false;
isPlaying = false;
nextFrame = -1;
- curLine = NULL;
- // Update displays
UpdateDisplays(true);
// Clean up video data
- wxRemoveFile(tempfile);
- tempfile = _T("");
- videoName = _T("");
+ videoName.clear();
tempFrame.Clear();
// Remove provider
- if (provider) {
- delete provider;
- provider = NULL;
- }
- delete subsProvider;
- subsProvider = NULL;
+ provider.reset();
+ subsProvider.reset();
}
-/// @brief Reload video
-///
-void VideoContext::Reload() {
- if (IsLoaded()) {
- wxString name = videoName;
- int n = frame_n;
- SetVideo(_T(""));
- SetVideo(name);
- JumpToFrame(n);
- }
-}
-
-/// @brief Sets video filename
-/// @param filename
-///
void VideoContext::SetVideo(const wxString &filename) {
- // Unload video
+ Stop();
Reset();
+ if (filename.empty()) return;
- // Load video
- if (!filename.IsEmpty()) {
+ try {
+ grid->CommitChanges(true);
+
+ // Set GL context
+ GetGLContext(displayList.front())->SetCurrent(*displayList.front());
+
+ // Choose a provider
+ provider.reset(VideoProviderFactoryManager::GetProvider(filename));
+
+ // Get subtitles provider
try {
- grid->CommitChanges(true);
-
- // Set GL context
- GetGLContext(displayList.front())->SetCurrent(*displayList.front());
-
- // Choose a provider
- provider = VideoProviderFactoryManager::GetProvider(filename);
- loaded = provider != NULL;
-
- // Get subtitles provider
- try {
- subsProvider = SubtitlesProviderFactoryManager::GetProvider();
- }
- catch (wxString err) { wxMessageBox(_T("Error while loading subtitles provider: ") + err,_T("Subtitles provider")); }
- catch (const wchar_t *err) { wxMessageBox(_T("Error while loading subtitles provider: ") + wxString(err),_T("Subtitles provider")); }
-
- KeyFrames.Clear();
- // load keyframes if available
- if (provider->AreKeyFramesLoaded()) {
- KeyFrames = provider->GetKeyFrames();
- keyFramesLoaded = true;
- }
- else {
- keyFramesLoaded = false;
- }
-
- // Set frame rate
- fps = provider->GetFPS();
- // does this provider need special vfr treatment?
- if (provider->NeedsVFRHack()) {
- // FIXME:
- // Unfortunately, this hack does not actually work for the one
- // provider that needs it (Avisynth). Go figure.
- bool isVfr = provider->IsVFR();
- if (!isVfr || provider->IsNativelyByFrames()) {
- VFR_Input.SetCFR(fps);
- if (VFR_Output.GetFrameRateType() != VFR) VFR_Output.SetCFR(fps);
- }
- else {
- FrameRate temp = provider->GetTrueFrameRate();
- provider->OverrideFrameTimeList(temp.GetFrameTimeList());
- }
- }
-
- // Gather video parameters
- length = provider->GetFrameCount();
- w = provider->GetWidth();
- h = provider->GetHeight();
-
- // Set filename
- videoName = filename;
- config::mru->Add("Video", STD_STR(filename));
- wxFileName fn(filename);
- StandardPaths::SetPathValue(_T("?video"),fn.GetPath());
-
- // Get frame
- frame_n = 0;
-
- // Show warning
- wxString warning = provider->GetWarning().c_str();
- if (!warning.IsEmpty()) wxMessageBox(warning,_T("Warning"),wxICON_WARNING | wxOK);
-
- hasSubtitles = false;
- if (filename.Right(4).Lower() == L".mkv") {
- hasSubtitles = MatroskaWrapper::HasSubtitles(filename);
- }
-
- UpdateDisplays(true);
+ subsProvider.reset(SubtitlesProviderFactoryManager::GetProvider());
}
-
- catch (wxString &e) {
- wxMessageBox(e,_T("Error setting video"),wxICON_ERROR | wxOK);
+ catch (wxString err) { wxMessageBox(_T("Error while loading subtitles provider: ") + err,_T("Subtitles provider")); }
+ catch (const wchar_t *err) { wxMessageBox(_T("Error while loading subtitles provider: ") + wxString(err),_T("Subtitles provider")); }
+
+ keyFrames = provider->GetKeyFrames();
+
+ // Set frame rate
+ videoFPS = provider->GetFPS();
+ if (ovrFPS.IsLoaded()) {
+ int ovr = wxMessageBox(_("You already have timecodes loaded. Would you like to replace them with timecodes from the video file?"), _("Replace timecodes?"), wxYES_NO | wxICON_QUESTION);
+ if (ovr == wxYES) {
+ ovrFPS = agi::vfr::Framerate();
+ ovrTimecodeFile.clear();
+ }
}
+
+ // Gather video parameters
+ length = provider->GetFrameCount();
+
+ // Set filename
+ videoName = filename;
+ config::mru->Add("Video", STD_STR(filename));
+ wxFileName fn(filename);
+ StandardPaths::SetPathValue(_T("?video"),fn.GetPath());
+
+ // Get frame
+ frame_n = 0;
+
+ // Show warning
+ wxString warning = provider->GetWarning();
+ if (!warning.empty()) wxMessageBox(warning,_T("Warning"),wxICON_WARNING | wxOK);
+
+ hasSubtitles = false;
+ if (filename.Right(4).Lower() == L".mkv") {
+ hasSubtitles = MatroskaWrapper::HasSubtitles(filename);
+ }
+
+ UpdateDisplays(true);
+ }
+
+ catch (wxString &e) {
+ wxMessageBox(e,_T("Error setting video"),wxICON_ERROR | wxOK);
}
}
-/// @brief Add new display
-/// @param display
-/// @return
-///
void VideoContext::AddDisplay(VideoDisplay *display) {
for (std::list::iterator cur=displayList.begin();cur!=displayList.end();cur++) {
if ((*cur) == display) return;
@@ -309,15 +224,12 @@ void VideoContext::AddDisplay(VideoDisplay *display) {
displayList.push_back(display);
}
-/// @brief Remove display
-/// @param display
-///
void VideoContext::RemoveDisplay(VideoDisplay *display) {
displayList.remove(display);
}
void VideoContext::UpdateDisplays(bool full, bool seek) {
- if (!loaded) return;
+ if (!IsLoaded()) return;
for (std::list::iterator cur=displayList.begin();cur!=displayList.end();cur++) {
VideoDisplay *display = *cur;
@@ -343,9 +255,8 @@ void VideoContext::UpdateDisplays(bool full, bool seek) {
}
}
-/// @brief Refresh subtitles
void VideoContext::Refresh () {
- if (subsProvider) {
+ if (subsProvider.get()) {
AssExporter exporter(grid->ass);
exporter.AddAutoFilters();
try {
@@ -358,12 +269,8 @@ void VideoContext::Refresh () {
UpdateDisplays(false);
}
-/// @brief Jumps to a frame and update display
-/// @param n
-/// @return
-///
void VideoContext::JumpToFrame(int n) {
- if (!loaded) return;
+ if (!IsLoaded()) return;
// Prevent intervention during playback
if (isPlaying && n != playNextFrame) return;
@@ -372,30 +279,14 @@ void VideoContext::JumpToFrame(int n) {
UpdateDisplays(false, true);
- // Update grid
static agi::OptionValue* highlight = OPT_GET("Subtitle/Grid/Highlight Subtitles in Frame");
if (!isPlaying && highlight->GetBool()) grid->Refresh(false);
}
-
-
-/// @brief Jumps to a specific time
-/// @param ms
-/// @param exact
-///
-void VideoContext::JumpToTime(int ms,bool exact) {
- int frame;
- if (exact) frame = VFR_Output.PFrameAtTime(ms);
- else frame = VFR_Output.GetFrameAtTime(ms);
- JumpToFrame(frame);
+void VideoContext::JumpToTime(int ms, agi::vfr::Time end) {
+ JumpToFrame(FrameAtTime(ms, end));
}
-
-
-/// @brief Get GL context
-/// @param canvas
-/// @return
-///
wxGLContext *VideoContext::GetGLContext(wxGLCanvas *canvas) {
if (!glContext) {
glContext = new wxGLContext(canvas);
@@ -404,25 +295,17 @@ wxGLContext *VideoContext::GetGLContext(wxGLCanvas *canvas) {
return glContext;
}
-
-
-/// @brief Requests a new frame
-/// @param n
-/// @param raw
-/// @return
-///
AegiVideoFrame VideoContext::GetFrame(int n,bool raw) {
// Current frame if -1
if (n == -1) n = frame_n;
- // Get frame
AegiVideoFrame frame = provider->GetFrame(n);
// Raster subtitles if available/necessary
- if (!raw && subsProvider) {
+ if (!raw && subsProvider.get()) {
tempFrame.CopyFrom(frame);
try {
- subsProvider->DrawSubtitles(tempFrame,VFR_Input.GetTimeAtFrame(n,true,true)/1000.0);
+ subsProvider->DrawSubtitles(tempFrame,videoFPS.TimeAtFrame(n)/1000.0);
}
catch (...) {
wxLogError(L"Subtitle rendering for the current frame failed.\n");
@@ -434,9 +317,13 @@ AegiVideoFrame VideoContext::GetFrame(int n,bool raw) {
else return frame;
}
-/// @brief Save snapshot
-/// @param raw
-///
+int VideoContext::GetWidth() const {
+ return provider->GetWidth();
+}
+int VideoContext::GetHeight() const {
+ return provider->GetHeight();
+}
+
void VideoContext::SaveSnapshot(bool raw) {
// Get folder
static agi::OptionValue* ssPath = OPT_GET("Path/Screenshot");
@@ -452,7 +339,7 @@ void VideoContext::SaveSnapshot(bool raw) {
}
// Find out where the ?specifier points to
basepath = StandardPaths::DecodePath(option);
- // If whereever that is isn't defined, we can't save there
+ // If where ever that is isn't defined, we can't save there
if ((basepath == _T("\\")) || (basepath == _T("/"))) {
// So save to the current user's home dir instead
basepath = wxGetHomeDir();
@@ -472,21 +359,13 @@ void VideoContext::SaveSnapshot(bool raw) {
if (!tryPath.FileExists()) break;
}
- // Save
GetFrame(frame_n,raw).GetImage().SaveFile(path,wxBITMAP_TYPE_PNG);
}
-/// @brief Get dimensions of script
-/// @param sw
-/// @param sh
-///
void VideoContext::GetScriptSize(int &sw,int &sh) {
grid->ass->GetResolution(sw,sh);
}
-/// @brief Play the next frame, possibly with audio
-/// @return
-///
void VideoContext::PlayNextFrame() {
if (isPlaying)
return;
@@ -495,12 +374,9 @@ void VideoContext::PlayNextFrame() {
JumpToFrame(frame_n + 1);
// Start playing audio
if (playAudioOnStep->GetBool())
- audio->Play(VFR_Output.GetTimeAtFrame(thisFrame),VFR_Output.GetTimeAtFrame(thisFrame + 1));
+ audio->Play(TimeAtFrame(thisFrame),TimeAtFrame(thisFrame + 1));
}
-/// @brief Play the previous frame, possibly with audio
-/// @return
-///
void VideoContext::PlayPrevFrame() {
if (isPlaying)
return;
@@ -509,14 +385,10 @@ void VideoContext::PlayPrevFrame() {
JumpToFrame(frame_n -1);
// Start playing audio
if (playAudioOnStep->GetBool())
- audio->Play(VFR_Output.GetTimeAtFrame(thisFrame - 1),VFR_Output.GetTimeAtFrame(thisFrame));
+ audio->Play(TimeAtFrame(thisFrame - 1),TimeAtFrame(thisFrame));
}
-/// @brief Play
-/// @return
-///
void VideoContext::Play() {
- // Stop if already playing
if (isPlaying) {
Stop();
return;
@@ -527,7 +399,7 @@ void VideoContext::Play() {
endFrame = -1;
// Start playing audio
- audio->Play(VFR_Output.GetTimeAtFrame(startFrame),-1);
+ audio->Play(TimeAtFrame(startFrame),-1);
//audio->Play will override this if we put it before, so put it after.
isPlaying = true;
@@ -538,14 +410,7 @@ void VideoContext::Play() {
playback.Start(10);
}
-
-
-
-/// @brief Play line
-/// @return
-///
void VideoContext::PlayLine() {
- // Get line
AssDialogue *curline = grid->GetActiveLine();
if (!curline) return;
@@ -554,8 +419,8 @@ void VideoContext::PlayLine() {
// Set variables
isPlaying = true;
- startFrame = VFR_Output.GetFrameAtTime(curline->Start.GetMS(),true);
- endFrame = VFR_Output.GetFrameAtTime(curline->End.GetMS(),false);
+ startFrame = FrameAtTime(curline->Start.GetMS(),agi::vfr::START);
+ endFrame = FrameAtTime(curline->End.GetMS(),agi::vfr::END);
// Jump to start
playNextFrame = startFrame;
@@ -569,8 +434,6 @@ void VideoContext::PlayLine() {
playback.Start(10);
}
-/// @brief Stop
-///
void VideoContext::Stop() {
if (isPlaying) {
playback.Stop();
@@ -579,10 +442,6 @@ void VideoContext::Stop() {
}
}
-/// @brief Play timer
-/// @param event
-/// @return
-///
void VideoContext::OnPlayTimer(wxTimerEvent &event) {
// Lock
wxMutexError res = playMutex.TryLock();
@@ -594,12 +453,12 @@ void VideoContext::OnPlayTimer(wxTimerEvent &event) {
int dif = playTime.Time();
// Find next frame
- int startMs = VFR_Output.GetTimeAtFrame(startFrame);
+ int startMs = TimeAtFrame(startFrame);
int nextFrame = frame_n;
int i=0;
for (i=0;i<10;i++) {
if (nextFrame >= length) break;
- if (dif < VFR_Output.GetTimeAtFrame(nextFrame) - startMs) {
+ if (dif < TimeAtFrame(nextFrame) - startMs) {
break;
}
nextFrame++;
@@ -615,7 +474,7 @@ void VideoContext::OnPlayTimer(wxTimerEvent &event) {
if (nextFrame == frame_n) return;
// Next frame is before or over 2 frames ahead, so force audio resync
- if (audio->player && keepAudioSync && (nextFrame < frame_n || nextFrame > frame_n + 2)) audio->player->SetCurrentPosition(audio->GetSampleAtMS(VFR_Output.GetTimeAtFrame(nextFrame)));
+ if (audio->player && keepAudioSync && (nextFrame < frame_n || nextFrame > frame_n + 2)) audio->player->SetCurrentPosition(audio->GetSampleAtMS(TimeAtFrame(nextFrame)));
// Jump to next frame
playNextFrame = nextFrame;
@@ -624,7 +483,7 @@ void VideoContext::OnPlayTimer(wxTimerEvent &event) {
// Sync audio
if (keepAudioSync && nextFrame % 10 == 0 && audio && audio->provider && audio->player) {
- int64_t audPos = audio->GetSampleAtMS(VFR_Output.GetTimeAtFrame(nextFrame));
+ int64_t audPos = audio->GetSampleAtMS(TimeAtFrame(nextFrame));
int64_t curPos = audio->player->GetCurrentPosition();
int delta = int(audPos-curPos);
if (delta < 0) delta = -delta;
@@ -633,67 +492,7 @@ void VideoContext::OnPlayTimer(wxTimerEvent &event) {
}
}
-/// @brief Get name of temp work file
-/// @return
-///
-wxString VideoContext::GetTempWorkFile () {
- if (tempfile.IsEmpty()) {
- tempfile = wxFileName::CreateTempFileName(_T("aegisub"));
- wxRemoveFile(tempfile);
- tempfile += _T(".ass");
- }
- return tempfile;
-}
-
-/// @brief Get keyframes
-/// @return
-///
-wxArrayInt VideoContext::GetKeyFrames() {
- if (OverKeyFramesLoaded()) return overKeyFrames;
- return KeyFrames;
-}
-
-/// @brief Set keyframes
-/// @param frames
-///
-void VideoContext::SetKeyFrames(wxArrayInt frames) {
- KeyFrames = frames;
-}
-
-/// @brief Set keyframe override
-/// @param frames
-///
-void VideoContext::SetOverKeyFrames(wxArrayInt frames) {
- overKeyFrames = frames;
- overKeyFramesLoaded = true;
-}
-
-/// @brief Close keyframes
-///
-void VideoContext::CloseOverKeyFrames() {
- overKeyFrames.Clear();
- overKeyFramesLoaded = false;
-}
-
-/// @brief Check if override keyframes are loaded
-/// @return
-///
-bool VideoContext::OverKeyFramesLoaded() {
- return overKeyFramesLoaded;
-}
-
-/// @brief Check if keyframes are loaded
-/// @return
-///
-bool VideoContext::KeyFramesLoaded() {
- return overKeyFramesLoaded || keyFramesLoaded;
-}
-
-/// @brief Calculate aspect ratio
-/// @param type
-/// @return
-///
-double VideoContext::GetARFromType(int type) {
+double VideoContext::GetARFromType(int type) const {
if (type == 0) return (double)VideoContext::Get()->GetWidth()/(double)VideoContext::Get()->GetHeight();
if (type == 1) return 4.0/3.0;
if (type == 2) return 16.0/9.0;
@@ -701,18 +500,77 @@ double VideoContext::GetARFromType(int type) {
return 1.0; //error
}
-/// @brief Sets aspect ratio
-/// @param _type
-/// @param value
-///
-void VideoContext::SetAspectRatio(int _type, double value) {
- // Get value
- if (_type != 4) value = GetARFromType(_type);
+void VideoContext::SetAspectRatio(int type, double value) {
+ if (type != 4) value = GetARFromType(type);
if (value < 0.5) value = 0.5;
if (value > 5.0) value = 5.0;
- // Set
- arType = _type;
+ arType = type;
arValue = value;
UpdateDisplays(true);
}
+
+void VideoContext::LoadKeyframes(wxString filename) {
+ if (filename == keyFramesFilename || filename.empty()) return;
+ keyFrames = KeyFrameFile::Load(filename);
+ keyFramesFilename = filename;
+ Refresh();
+}
+
+void VideoContext::SaveKeyframes(wxString filename) {
+ KeyFrameFile::Save(filename, GetKeyFrames());
+}
+
+void VideoContext::CloseKeyframes() {
+ keyFramesFilename.clear();
+ if (provider.get()) {
+ keyFrames = provider->GetKeyFrames();
+ }
+ else {
+ keyFrames.clear();
+ }
+ Refresh();
+}
+
+void VideoContext::LoadTimecodes(wxString filename) {
+ if (filename == ovrTimecodeFile || filename.empty()) return;
+ try {
+ ovrFPS = agi::vfr::Framerate(STD_STR(filename));
+ ovrTimecodeFile = filename;
+ config::mru->Add("Timecodes", STD_STR(filename));
+ Refresh();
+ }
+ catch (const agi::acs::AcsError&) {
+ wxLogError(L"Could not open file " + filename);
+ }
+ catch (const agi::vfr::Error& e) {
+ wxLogError(L"Timecode file parse error: %s", e.GetMessage().c_str());
+ }
+}
+void VideoContext::SaveTimecodes(wxString filename) {
+ try {
+ ovrFPS.Save(STD_STR(filename), IsLoaded() ? length : -1);
+ config::mru->Add("Timecodes", STD_STR(filename));
+ }
+ catch(const agi::acs::AcsError&) {
+ wxLogError(L"Could not write to " + filename);
+ }
+}
+void VideoContext::CloseTimecodes() {
+ ovrFPS = agi::vfr::Framerate();
+ ovrTimecodeFile.clear();
+ Refresh();
+}
+
+int VideoContext::TimeAtFrame(int frame, agi::vfr::Time type) const {
+ if (ovrFPS.IsLoaded()) {
+ return ovrFPS.TimeAtFrame(frame, type);
+ }
+ return videoFPS.TimeAtFrame(frame, type);
+}
+int VideoContext::FrameAtTime(int time, agi::vfr::Time type) const {
+ if (ovrFPS.IsLoaded()) {
+ return ovrFPS.FrameAtTime(time, type);
+ }
+ return videoFPS.FrameAtTime(time, type);
+}
diff --git a/aegisub/src/video_context.h b/aegisub/src/video_context.h
index 956cfe038..f715bec00 100644
--- a/aegisub/src/video_context.h
+++ b/aegisub/src/video_context.h
@@ -38,6 +38,7 @@
#include
#include
+#include
#include
#include
@@ -56,12 +57,14 @@
#include
#endif
+#include
#include "video_frame.h"
class SubtitlesGrid;
class AudioProvider;
class AudioDisplay;
class AssDialogue;
+class KeyFrameFile;
class SubtitlesProvider;
class VideoProvider;
class VideoDisplay;
@@ -77,11 +80,9 @@ namespace agi {
/// DOCME
class VideoContext : public wxEvtHandler {
friend class AudioProvider;
+ friend class KeyFrameFile;
private:
- /// DOCME
- static VideoContext *instance;
-
/// DOCME
std::list displayList;
@@ -94,27 +95,14 @@ private:
/// DOCME
AegiVideoFrame tempFrame;
+ /// DOCME
+ std::auto_ptr provider;
/// DOCME
- wxString tempfile;
+ std::auto_ptr subsProvider;
/// DOCME
- VideoProvider *provider;
-
- /// DOCME
- SubtitlesProvider *subsProvider;
-
- /// DOCME
- bool keyFramesLoaded;
-
- /// DOCME
- bool overKeyFramesLoaded;
-
- /// DOCME
- wxArrayInt KeyFrames;
-
- /// DOCME
- wxArrayInt overKeyFrames;
+ std::vector keyFrames;
/// DOCME
wxString keyFramesFilename;
@@ -140,29 +128,18 @@ private:
/// DOCME
int nextFrame;
- /// DOCME
- bool loaded;
-
/// DOCME
bool isPlaying;
/// DOCME
bool keepAudioSync;
- /// DOCME
-
- /// DOCME
- int w,h;
-
/// DOCME
int frame_n;
/// DOCME
int length;
- /// DOCME
- double fps;
-
/// DOCME
double arValue;
@@ -171,24 +148,28 @@ private:
bool hasSubtitles;
+ wxString ovrTimecodeFile;
+
agi::OptionValue* playAudioOnStep;
void OnPlayTimer(wxTimerEvent &event);
+ agi::vfr::Framerate videoFPS;
+ agi::vfr::Framerate ovrFPS;
+
public:
/// DOCME
SubtitlesGrid *grid;
- /// DOCME
+ /// File name of currently open video, if any
wxString videoName;
-
- /// DOCME
- AssDialogue *curLine;
-
/// DOCME
AudioDisplay *audio;
+ const agi::vfr::Framerate &VFR_Input;
+ const agi::vfr::Framerate &VFR_Output;
+
VideoContext();
~VideoContext();
@@ -196,110 +177,114 @@ public:
void RemoveDisplay(VideoDisplay *display);
- /// @brief DOCME
- /// @return
- ///
- VideoProvider *GetProvider() { return provider; }
+ /// @brief Get the video provider used for the currently open video
+ VideoProvider *GetProvider() const { return provider.get(); }
AegiVideoFrame GetFrame(int n,bool raw=false);
+ /// @brief Save the currently displayed frame as an image
+ /// @param raw Should the frame have subtitles?
void SaveSnapshot(bool raw);
wxGLContext *GetGLContext(wxGLCanvas *canvas);
- /// @brief DOCME
- /// @return
- bool IsLoaded() { return loaded; }
+ /// @brief Is there a video loaded?
+ bool IsLoaded() const { return !!provider.get(); }
- /// @brief DOCME
- /// @return
- bool IsPlaying() { return isPlaying; }
+ /// @brief Is the video currently playing?
+ bool IsPlaying() const { return isPlaying; }
/// @brief Does the video file loaded have muxed subtitles that we can load?
- bool HasSubtitles() {return hasSubtitles; }
+ bool HasSubtitles() const { return hasSubtitles; }
/// @brief DOCME
/// @param sync
/// @return
void EnableAudioSync(bool sync = true) { keepAudioSync = sync; }
+ /// @brief Get the width of the currently open video
+ int GetWidth() const;
- /// @brief DOCME
- /// @return
- int GetWidth() { return w; }
+ /// @brief Get the height of the currently open video
+ int GetHeight() const;
- /// @brief DOCME
- /// @return
- int GetHeight() { return h; }
+ /// @brief Get the length in frames of the currently open video
+ int GetLength() const { return length; }
- /// @brief DOCME
- /// @return
- int GetLength() { return length; }
+ /// @brief Get the current frame number
+ int GetFrameN() const { return frame_n; }
- /// @brief DOCME
- /// @return
- int GetFrameN() { return frame_n; }
-
- /// @brief DOCME
- /// @return
- double GetFPS() { return fps; }
-
- /// @brief DOCME
- /// @param _fps
- /// @return
- void SetFPS(double fps) { this->fps = fps; }
-
- double GetARFromType(int type);
+ double GetARFromType(int type) const;
void SetAspectRatio(int type,double value=1.0);
/// @brief DOCME
/// @return
- int GetAspectRatioType() { return arType; }
+ int GetAspectRatioType() const { return arType; }
/// @brief DOCME
/// @return
- double GetAspectRatioValue() { return arValue; }
+ double GetAspectRatioValue() const { return arValue; }
+ /// @brief Open a new video
+ /// @param filename Video to open, or empty to close the current video
void SetVideo(const wxString &filename);
+ /// @brief Close the video, keyframes and timecodes
void Reset();
- void Reload();
+ /// @brief Jump to the beginning of a frame
+ /// @param n Frame number to jump to
void JumpToFrame(int n);
- void JumpToTime(int ms,bool exact=false);
+ /// @brief Jump to a time
+ /// @param ms Time to jump to in milliseconds
+ /// @param end Type of time
+ void JumpToTime(int ms, agi::vfr::Time end = agi::vfr::START);
+ /// @brief Refresh the subtitle provider
void Refresh();
+
/// @brief Update the video display
/// @param full Recalculate size and slider lengths
/// @param seek Update is just a seek and file has not changed
void UpdateDisplays(bool full, bool seek = false);
+ /// @brief Get the height and width of the current script
+ /// @param[out] w Width
+ /// @param[out] h Height
+ ///
+ /// This probably shouldn't be in VideoContext
void GetScriptSize(int &w,int &h);
- wxString GetTempWorkFile ();
+ /// Starting playing the video
void Play();
+ /// Play the next frame then stop
void PlayNextFrame();
+ /// Play the previous frame then stop
void PlayPrevFrame();
+ /// Seek to the beginning of the current line, then play to the end of it
void PlayLine();
+ /// Stop playing
void Stop();
- wxArrayInt GetKeyFrames();
- void SetKeyFrames(wxArrayInt frames);
- void SetOverKeyFrames(wxArrayInt frames);
- void CloseOverKeyFrames();
- bool OverKeyFramesLoaded();
- bool KeyFramesLoaded();
+ const std::vector& GetKeyFrames() const { return keyFrames; };
+ wxString GetKeyFramesName() const { return keyFramesFilename; }
+ void LoadKeyframes(wxString filename);
+ void SaveKeyframes(wxString filename);
+ void CloseKeyframes();
+ bool OverKeyFramesLoaded() const { return !keyFramesFilename.empty(); }
+ bool KeyFramesLoaded() const { return !keyFrames.empty(); }
- /// @brief DOCME
- /// @return
- ///
- wxString GetKeyFramesName() { return keyFramesFilename; }
+ wxString GetTimecodesName() const { return ovrTimecodeFile; }
+ void LoadTimecodes(wxString filename);
+ void SaveTimecodes(wxString filename);
+ void CloseTimecodes();
+ bool OverTimecodesLoaded() const { return ovrFPS.IsLoaded(); }
+ bool TimecodesLoaded() const { return videoFPS.IsLoaded() || ovrFPS.IsLoaded(); };
- /// @brief DOCME
- /// @param name
- ///
- void SetKeyFramesName(wxString name) { keyFramesFilename = name; }
+ const agi::vfr::Framerate& FPS() const { return ovrFPS.IsLoaded() ? ovrFPS : videoFPS; }
+
+ int TimeAtFrame(int frame, agi::vfr::Time type = agi::vfr::EXACT) const;
+ int FrameAtTime(int time, agi::vfr::Time type = agi::vfr::EXACT) const;
static VideoContext *Get();
- static void Clear();
DECLARE_EVENT_TABLE()
};
diff --git a/aegisub/src/video_display.cpp b/aegisub/src/video_display.cpp
index 5edf5746d..e30a80c31 100644
--- a/aegisub/src/video_display.cpp
+++ b/aegisub/src/video_display.cpp
@@ -60,8 +60,8 @@
#include "hotkeys.h"
#include "options.h"
#include "main.h"
+#include "subs_grid.h"
#include "video_out_gl.h"
-#include "vfr.h"
#include "video_box.h"
#include "video_context.h"
#include "video_slider.h"
@@ -166,7 +166,7 @@ void VideoDisplay::SetFrame(int frameNumber) {
// Get time for frame
{
- int time = VFR_Output.GetTimeAtFrame(frameNumber, true, true);
+ int time = context->TimeAtFrame(frameNumber, agi::vfr::EXACT);
int h = time / 3600000;
int m = time % 3600000 / 60000;
int s = time % 60000 / 1000;
@@ -174,7 +174,7 @@ void VideoDisplay::SetFrame(int frameNumber) {
// Set the text box for frame number and time
PositionDisplay->SetValue(wxString::Format(L"%01i:%02i:%02i.%03i - %i", h, m, s, ms, frameNumber));
- if (context->GetKeyFrames().Index(frameNumber) != wxNOT_FOUND) {
+ if (std::binary_search(context->GetKeyFrames().begin(), context->GetKeyFrames().end(), frameNumber)) {
// Set the background color to indicate this is a keyframe
PositionDisplay->SetBackgroundColour(lagi_wxColour(OPT_GET("Colour/Subtitle Grid/Background/Selection")->GetColour()));
PositionDisplay->SetForegroundColour(lagi_wxColour(OPT_GET("Colour/Subtitle Grid/Selection")->GetColour()));
@@ -189,7 +189,7 @@ void VideoDisplay::SetFrame(int frameNumber) {
int startOff = 0;
int endOff = 0;
- if (AssDialogue *curLine = context->curLine) {
+ if (AssDialogue *curLine = context->grid->GetActiveLine()) {
startOff = time - curLine->Start.GetMS();
endOff = time - curLine->End.GetMS();
}
diff --git a/aegisub/src/video_provider_avs.cpp b/aegisub/src/video_provider_avs.cpp
index e385efeda..c1e983bee 100644
--- a/aegisub/src/video_provider_avs.cpp
+++ b/aegisub/src/video_provider_avs.cpp
@@ -50,7 +50,6 @@
#include "mkv_wrap.h"
#include "options.h"
#include "standard_paths.h"
-#include "vfr.h"
#include "vfw_wrap.h"
#include "video_context.h"
#include "video_provider_avs.h"
@@ -63,13 +62,9 @@ AvisynthVideoProvider::AvisynthVideoProvider(wxString _filename) {
AVSTRACE(wxString::Format(_T("AvisynthVideoProvider: Creating new AvisynthVideoProvider: \"%s\", \"%s\""), _filename, _subfilename));
bool mpeg2dec3_priority = true;
RGB32Video = NULL;
- fps = 0;
num_frames = 0;
last_fnum = -1;
- byFrame = false;
- KeyFrames.Clear();
- keyFramesLoaded = false;
- isVfr = false;
+ KeyFrames.clear();
AVSTRACE(_T("AvisynthVideoProvider: Opening video"));
RGB32Video = OpenVideo(_filename,mpeg2dec3_priority);
@@ -92,12 +87,6 @@ AvisynthVideoProvider::~AvisynthVideoProvider() {
AVSTRACE(_T("AvisynthVideoProvider: AvisynthVideoProvider destroyed"));
}
-
-
-////////////////////////////////////// VIDEO PROVIDER //////////////////////////////////////
-
-
-
/// @brief Actually open the video into Avisynth
/// @param _filename
/// @param mpeg2dec3_priority
@@ -109,7 +98,6 @@ PClip AvisynthVideoProvider::OpenVideo(wxString _filename, bool mpeg2dec3_priori
AVSTRACE(_T("AvisynthVideoProvider::OpenVideo: Got AVS mutex"));
AVSValue script;
- byFrame = false;
usedDirectShow = false;
decoderName = _("Unknown");
@@ -138,7 +126,6 @@ PClip AvisynthVideoProvider::OpenVideo(wxString _filename, bool mpeg2dec3_priori
AVSValue args[2] = { videoFilename, false };
script = env->Invoke("AviSource", AVSValue(args,2), argnames);
AVSTRACE(_T("AvisynthVideoProvider::OpenVideo: Successfully opened .avi file without audio"));
- byFrame = true;
decoderName = _T("AviSource");
}
@@ -155,10 +142,10 @@ PClip AvisynthVideoProvider::OpenVideo(wxString _filename, bool mpeg2dec3_priori
script = env->Invoke("Mpeg2Dec3_Mpeg2Source", videoFilename);
decoderName = _T("Mpeg2Dec3_Mpeg2Source");
- //if avisynth is 2.5.7 beta 2 or newer old mpeg2decs will crash without this
+ //if avisynth is 2.5.7 beta 2 or newer old mpeg2decs will crash without this
if (env->FunctionExists("SetPlanarLegacyAlignment")) {
AVSValue args[2] = { script, true };
- script = env->Invoke("SetPlanarLegacyAlignment", AVSValue(args,2));
+ script = env->Invoke("SetPlanarLegacyAlignment", AVSValue(args,2));
}
}
@@ -168,8 +155,8 @@ PClip AvisynthVideoProvider::OpenVideo(wxString _filename, bool mpeg2dec3_priori
script = env->Invoke("Mpeg2Source", videoFilename);
decoderName = _T("DGDecode_Mpeg2Source");
- //note that DGDecode will also have issues like if the version is too ancient but no sane person
- //would use that anyway
+ //note that DGDecode will also have issues like if the version is too ancient but no sane person
+ //would use that anyway
}
else if (extension == _T(".d2v") && env->FunctionExists("Mpeg2Source")) {
@@ -177,9 +164,9 @@ PClip AvisynthVideoProvider::OpenVideo(wxString _filename, bool mpeg2dec3_priori
script = env->Invoke("Mpeg2Source", videoFilename);
decoderName = _T("Mpeg2Source");
- //if avisynth is 2.5.7 beta 2 or newer old mpeg2decs will crash without this
- if (env->FunctionExists("SetPlanarLegacyAlignment"))
- script = env->Invoke("SetPlanarLegacyAlignment", script);
+ //if avisynth is 2.5.7 beta 2 or newer old mpeg2decs will crash without this
+ if (env->FunctionExists("SetPlanarLegacyAlignment"))
+ script = env->Invoke("SetPlanarLegacyAlignment", script);
}
// Some other format, such as mkv, mp4, ogm... try both flavors of DirectShowSource
@@ -253,30 +240,16 @@ PClip AvisynthVideoProvider::OpenVideo(wxString _filename, bool mpeg2dec3_priori
}
// Read keyframes and timecodes from MKV file
- isVfr = false;
- FrameRate temp;
bool mkvOpen = MatroskaWrapper::wrapper.IsOpen();
- KeyFrames.Clear();
+ KeyFrames.clear();
if (extension == _T(".mkv") || mkvOpen) {
// Parse mkv
if (!mkvOpen) MatroskaWrapper::wrapper.Open(_filename);
// Get keyframes
KeyFrames = MatroskaWrapper::wrapper.GetKeyFrames();
- keyFramesLoaded = true;
-
- // Ask to override timecodes
- int override = wxYES;
- if (VFR_Output.IsLoaded()) override = wxMessageBox(_("You already have timecodes loaded. Replace them with the timecodes from the Matroska file?"),_("Replace timecodes?"),wxYES_NO | wxICON_QUESTION);
- if (override == wxYES) {
- MatroskaWrapper::wrapper.SetToTimecodes(temp);
- isVfr = temp.GetFrameRateType() == VFR;
- if (isVfr) {
- MatroskaWrapper::wrapper.SetToTimecodes(VFR_Input);
- MatroskaWrapper::wrapper.SetToTimecodes(VFR_Output);
- trueFrameRate = temp;
- }
- }
+
+ MatroskaWrapper::wrapper.SetToTimecodes(vfr_fps);
// Close mkv
MatroskaWrapper::wrapper.Close();
@@ -284,16 +257,14 @@ PClip AvisynthVideoProvider::OpenVideo(wxString _filename, bool mpeg2dec3_priori
// check if we have windows, if so we can load keyframes from AVI files using VFW
#ifdef __WINDOWS__
else if (extension == _T(".avi")) {
- keyFramesLoaded = false;
- KeyFrames.Clear();
+ KeyFrames.clear();
KeyFrames = VFWWrapper::GetKeyFrames(_filename);
- keyFramesLoaded = true;
}
#endif /* __WINDOWS__ */
// Check if the file is all keyframes
bool isAllKeyFrames = true;
- for (unsigned int i=1; iInvoke("ConvertToRGB32", script);
AVSTRACE(_T("AvisynthVideoProvider::OpenVideo: Converted to RGB32"));
@@ -323,17 +295,10 @@ PClip AvisynthVideoProvider::OpenVideo(wxString _filename, bool mpeg2dec3_priori
/// @param _n
/// @return
///
-const AegiVideoFrame AvisynthVideoProvider::GetFrame(int _n) {
- // Transform n if overriden
- int n = _n;
- if (frameTime.Count()) {
- if (n < 0) n = 0;
- if (n >= (signed) frameTime.Count()) n = frameTime.Count()-1;
- int time = frameTime[n];
- double curFps = (double)vi.fps_numerator/(double)vi.fps_denominator;
- n = time * curFps / 1000.0;
+const AegiVideoFrame AvisynthVideoProvider::GetFrame(int n) {
+ if (vfr_fps.IsLoaded()) {
+ n = real_fps.FrameAtTime(vfr_fps.TimeAtFrame(n));
}
-
// Get avs frame
AVSTRACE(_T("AvisynthVideoProvider::GetFrame"));
wxMutexLocker lock(AviSynthMutex);
@@ -362,24 +327,11 @@ const AegiVideoFrame AvisynthVideoProvider::GetFrame(int _n) {
return final;
}
-
-/// @brief Override frame times
-/// @param list
-///
-void AvisynthVideoProvider::OverrideFrameTimeList(wxArrayInt list) {
- frameTime = list;
- num_frames = frameTime.Count();
-}
-
-
-
/// @brief Get warning
///
-wxString AvisynthVideoProvider::GetWarning() {
+wxString AvisynthVideoProvider::GetWarning() const {
if (usedDirectShow) return L"Warning! The file is being opened using Avisynth's DirectShowSource, which has unreliable seeking. Frame numbers might not match the real number. PROCEED AT YOUR OWN RISK!";
else return L"";
}
#endif
-
-
diff --git a/aegisub/src/video_provider_avs.h b/aegisub/src/video_provider_avs.h
index 556b407e9..389462475 100644
--- a/aegisub/src/video_provider_avs.h
+++ b/aegisub/src/video_provider_avs.h
@@ -34,22 +34,16 @@
/// @ingroup video_input
///
-
-///////////
-// Headers
#ifdef WITH_AVISYNTH
#include "avisynth_wrap.h"
#include "include/aegisub/video_provider.h"
-
/// DOCME
/// @class AvisynthVideoProvider
/// @brief DOCME
///
/// DOCME
class AvisynthVideoProvider: public VideoProvider, AviSynthWrapper {
-private:
-
/// DOCME
VideoInfo vi;
@@ -75,27 +69,11 @@ private:
/// DOCME
- double fps;
+ agi::vfr::Framerate real_fps;
+ agi::vfr::Framerate vfr_fps;
/// DOCME
- wxArrayInt frameTime;
-
- /// DOCME
- bool byFrame;
-
-
- /// DOCME
- wxArrayInt KeyFrames;
-
- /// DOCME
- bool keyFramesLoaded;
-
- /// DOCME
- bool isVfr;
-
- /// DOCME
- FrameRate trueFrameRate;
-
+ std::vector KeyFrames;
/// DOCME
PClip RGB32Video;
@@ -108,72 +86,16 @@ public:
const AegiVideoFrame GetFrame(int n);
- /// @brief // properties
- /// @return
- ///
- int GetPosition() { return last_fnum; };
-
- /// @brief DOCME
- /// @return
- ///
- int GetFrameCount() { return num_frames? num_frames: vi.num_frames; };
-
- /// @brief DOCME
- /// @return
- ///
- double GetFPS() { return (double)vi.fps_numerator/(double)vi.fps_denominator; };
-
- /// @brief DOCME
- /// @return
- ///
- int GetWidth() { return vi.width; };
-
- /// @brief DOCME
- /// @return
- ///
- int GetHeight() { return vi.height; };
-
- /// @brief DOCME
- /// @return
- ///
- bool AreKeyFramesLoaded() { return keyFramesLoaded; };
-
- /// @brief DOCME
- /// @return
- ///
- wxArrayInt GetKeyFrames() { return KeyFrames; };
-
- /// @brief DOCME
- /// @return
- ///
- bool IsVFR() { return isVfr; };
-
- /// @brief DOCME
- /// @return
- ///
- FrameRate GetTrueFrameRate() { return isVfr? trueFrameRate: FrameRate(); };
-
- void OverrideFrameTimeList(wxArrayInt list);
-
- /// @brief DOCME
- /// @return
- ///
- bool IsNativelyByFrames() { return byFrame; }
-
- /// @brief DOCME
- /// @return
- ///
- bool NeedsVFRHack() { return true; }
- wxString GetWarning();
-
- /// @brief DOCME
- /// @return
- ///
- wxString GetDecoderName() { return wxString(L"Avisynth/") + decoderName; }
+ int GetPosition() const { return last_fnum; };
+ int GetFrameCount() const { return num_frames? num_frames: vi.num_frames; };
+ agi::vfr::Framerate GetFPS() const { return vfr_fps.IsLoaded() ? vfr_fps : real_fps; };
+ int GetWidth() const { return vi.width; };
+ int GetHeight() const { return vi.height; };
+ std::vector GetKeyFrames() const { return KeyFrames; };
+ wxString GetWarning() const;
+ wxString GetDecoderName() const { return wxString(L"Avisynth/") + decoderName; }
};
-
-
/// DOCME
/// @class AvisynthVideoProviderFactory
/// @brief DOCME
@@ -188,7 +110,4 @@ public:
VideoProvider *CreateProvider(wxString video) { return new AvisynthVideoProvider(video); }
};
-
#endif
-
-
diff --git a/aegisub/src/video_provider_cache.cpp b/aegisub/src/video_provider_cache.cpp
index c0f94662d..85692c1b2 100644
--- a/aegisub/src/video_provider_cache.cpp
+++ b/aegisub/src/video_provider_cache.cpp
@@ -34,39 +34,43 @@
/// @ingroup video_input
///
-
-///////////
-// Headers
#include "config.h"
#include "main.h"
#include "options.h"
#include "video_provider_cache.h"
+/// DOCME
+/// @class CachedFrame
+/// @brief DOCME
+///
+/// DOCME
+struct CachedFrame {
+ /// DOCME
+ AegiVideoFrame frame;
+
+ /// DOCME
+ int n;
+};
/// @brief Constructor
/// @param parent
///
-VideoProviderCache::VideoProviderCache(VideoProvider *parent) {
- master = parent;
- cacheMax = 0;
- if (parent->WantsCaching())
- cacheMax = OPT_GET("Provider/Video/Cache/Size")->GetInt() << 20; // convert MB to bytes
- else
- cacheMax = 0;
+VideoProviderCache::VideoProviderCache(VideoProvider *parent)
+: master(parent)
+, cacheMax(OPT_GET("Provider/Video/Cache/Size")->GetInt() << 20) // convert MB to bytes
+{
}
-
-
/// @brief Destructor
///
VideoProviderCache::~VideoProviderCache() {
- delete master;
- ClearCache();
+ while (cache.size()) {
+ cache.front().frame.Clear();
+ cache.pop_front();
+ }
}
-
-
/// @brief Get frame
/// @param n
/// @return
@@ -88,21 +92,14 @@ const AegiVideoFrame VideoProviderCache::GetFrame(int n) {
const AegiVideoFrame *srcFrame = &frame;
// Cache frame
- pos = n;
Cache(n,*srcFrame);
return *srcFrame;
}
-
/// @brief Add to cache
/// @param n
/// @param frame
-/// @return
-///
void VideoProviderCache::Cache(int n,const AegiVideoFrame frame) {
- // Cache enabled?
- if (cacheMax == 0) return;
-
// Cache full, use frame at front
if (GetCurCacheSize() >= cacheMax) {
cache.push_back(cache.front());
@@ -119,17 +116,6 @@ void VideoProviderCache::Cache(int n,const AegiVideoFrame frame) {
cache.back().frame.CopyFrom(frame);
}
-
-
-/// @brief Clear cache
-///
-void VideoProviderCache::ClearCache() {
- while (cache.size()) {
- cache.front().frame.Clear();
- cache.pop_front();
- }
-}
-
/// @brief Get the current size of the cache
/// @return Returns the size in bytes
unsigned VideoProviderCache::GetCurCacheSize() {
@@ -138,103 +124,3 @@ unsigned VideoProviderCache::GetCurCacheSize() {
sz += i->frame.memSize;
return sz;
}
-
-
-/// @brief Wrapper methods
-/// @return
-///
-int VideoProviderCache::GetPosition() {
- return pos;
-}
-
-/// @brief DOCME
-/// @return
-///
-int VideoProviderCache::GetFrameCount() {
- return master->GetFrameCount();
-}
-
-/// @brief DOCME
-/// @return
-///
-int VideoProviderCache::GetWidth() {
- return master->GetWidth();
-}
-
-/// @brief DOCME
-/// @return
-///
-int VideoProviderCache::GetHeight() {
- return master->GetHeight();
-}
-
-/// @brief DOCME
-/// @return
-///
-double VideoProviderCache::GetFPS() {
- return master->GetFPS();
-}
-
-/// @brief DOCME
-/// @return
-///
-bool VideoProviderCache::IsVFR() {
- return master->IsVFR();
-}
-
-/// @brief DOCME
-/// @return
-///
-bool VideoProviderCache::AreKeyFramesLoaded() {
- return master->AreKeyFramesLoaded();
-}
-
-/// @brief DOCME
-/// @return
-///
-wxArrayInt VideoProviderCache::GetKeyFrames() {
- return master->GetKeyFrames();
-}
-
-/// @brief DOCME
-/// @return
-///
-FrameRate VideoProviderCache::GetTrueFrameRate() {
- return master->GetTrueFrameRate();
-}
-
-/// @brief DOCME
-/// @param list
-///
-void VideoProviderCache::OverrideFrameTimeList(std::vector list) {
- master->OverrideFrameTimeList(list);
-}
-
-/// @brief DOCME
-/// @return
-///
-bool VideoProviderCache::IsNativelyByFrames() {
- return master->IsNativelyByFrames();
-}
-
-/// @brief DOCME
-/// @return
-///
-bool VideoProviderCache::NeedsVFRHack() {
- return master->NeedsVFRHack();
-}
-
-/// @brief DOCME
-/// @return
-///
-wxString VideoProviderCache::GetWarning() {
- return master->GetWarning();
-}
-
-/// @brief DOCME
-///
-wxString VideoProviderCache::GetDecoderName() {
- return master->GetDecoderName();
-}
-
-
diff --git a/aegisub/src/video_provider_cache.h b/aegisub/src/video_provider_cache.h
index c73faf307..4bd5914c7 100644
--- a/aegisub/src/video_provider_cache.h
+++ b/aegisub/src/video_provider_cache.h
@@ -34,34 +34,14 @@
/// @ingroup video_input
///
-
-
-
-//////////
-// Headers
#ifndef AGI_PRE
#include
+#include
#endif
#include "include/aegisub/video_provider.h"
-#include "vfr.h"
-
-
-/// DOCME
-/// @class CachedFrame
-/// @brief DOCME
-///
-/// DOCME
-class CachedFrame {
-public:
-
- /// DOCME
- AegiVideoFrame frame;
-
- /// DOCME
- int n;
-};
+struct CachedFrame;
/// DOCME
/// @class VideoProviderCache
@@ -69,10 +49,8 @@ public:
///
/// DOCME
class VideoProviderCache : public VideoProvider {
-private:
-
/// DOCME
- VideoProvider *master;
+ std::auto_ptr master;
/// DOCME
unsigned int cacheMax;
@@ -80,16 +58,11 @@ private:
/// DOCME
std::list cache;
- /// DOCME
- int pos;
-
void Cache(int n,const AegiVideoFrame frame);
AegiVideoFrame GetCachedFrame(int n);
-protected:
// Cache functions
unsigned GetCurCacheSize();
- void ClearCache();
public:
// Base methods
@@ -98,20 +71,14 @@ public:
virtual ~VideoProviderCache();
// Override the following methods:
- virtual int GetPosition(); // Get the number of the last frame loaded
- virtual int GetFrameCount(); // Get total number of frames
- virtual int GetWidth(); // Returns the video width in pixels
- virtual int GetHeight(); // Returns the video height in pixels
- virtual double GetFPS(); // Get framerate in frames per second
- virtual bool AreKeyFramesLoaded();
- virtual bool IsVFR();
- virtual wxArrayInt GetKeyFrames();
- virtual FrameRate GetTrueFrameRate();
- virtual void OverrideFrameTimeList(std::vector list); // Override the list with the provided one, for VFR handling
- virtual bool IsNativelyByFrames();
- virtual bool NeedsVFRHack();
- virtual wxString GetWarning();
- virtual wxString GetDecoderName();
+ virtual int GetPosition() const { return master->GetPosition(); }
+ virtual int GetFrameCount() const { return master->GetFrameCount(); }
+ virtual int GetWidth() const { return master->GetWidth(); }
+ virtual int GetHeight() const { return master->GetHeight(); }
+ virtual agi::vfr::Framerate GetFPS() const { return master->GetFPS(); }
+ virtual std::vector GetKeyFrames() const { return master->GetKeyFrames(); }
+ virtual wxString GetWarning() const { return master->GetWarning(); }
+ virtual wxString GetDecoderName() const { return master->GetDecoderName(); }
+
+
};
-
-
diff --git a/aegisub/src/video_provider_dummy.cpp b/aegisub/src/video_provider_dummy.cpp
index 87ebca71b..883784867 100644
--- a/aegisub/src/video_provider_dummy.cpp
+++ b/aegisub/src/video_provider_dummy.cpp
@@ -34,9 +34,6 @@
/// @ingroup video_input
///
-
-///////////
-// Headers
#include "config.h"
#ifndef AGI_PRE
@@ -46,18 +43,6 @@
#include "colorspace.h"
#include "video_provider_dummy.h"
-
-///////////
-// Factory
-// Shouldn't be needed
-/*class DummyVideoProviderFactory : public VideoProviderFactory {
-public:
- VideoProvider *CreateProvider(wxString video,double fps=0.0) { return new DummyVideoProvider(video,fps); }
- DummyVideoProviderFactory() : VideoProviderFactory(_T("dummy")) {}
-} registerDummyVideo; */
-
-
-
/// @brief Constructor
/// @param _fps
/// @param frames
@@ -130,8 +115,6 @@ void DummyVideoProvider::Create(double _fps, int frames, int _width, int _height
}
}
-
-
/// @brief Parsing constructor
/// @param filename
///
@@ -194,8 +177,6 @@ DummyVideoProvider::DummyVideoProvider(wxString filename)
Create(fps, _frames, _width, _height, wxColour(red, green, blue), pattern);
}
-
-
/// @brief Direct constructor
/// @param _fps
/// @param frames
@@ -208,16 +189,12 @@ DummyVideoProvider::DummyVideoProvider(double _fps, int frames, int _width, int
Create(_fps, frames, _width, _height, colour, pattern);
}
-
-
/// @brief Destructor
///
DummyVideoProvider::~DummyVideoProvider() {
frame.Clear();
}
-
-
/// @brief Construct a fake filename describing the video
/// @param fps
/// @param frames
@@ -231,8 +208,6 @@ wxString DummyVideoProvider::MakeFilename(double fps, int frames, int _width, in
return wxString::Format(_T("?dummy:%f:%d:%d:%d:%d:%d:%d:%s"), fps, frames, _width, _height, colour.Red(), colour.Green(), colour.Blue(), pattern?_T("c"):_T(""));
}
-
-
/// @brief Get frame
/// @param n
/// @return
@@ -241,59 +216,3 @@ const AegiVideoFrame DummyVideoProvider::GetFrame(int n) {
lastFrame = n;
return frame;
}
-
-
-
-/// @brief Get position
-/// @return
-///
-int DummyVideoProvider::GetPosition() {
- return lastFrame;
-}
-
-
-
-/// @brief Get frame count
-/// @return
-///
-int DummyVideoProvider::GetFrameCount() {
- return framecount;
-}
-
-
-
-/// @brief Get width
-/// @return
-///
-int DummyVideoProvider::GetWidth() {
- return width;
-}
-
-
-
-/// @brief Get height
-/// @return
-///
-int DummyVideoProvider::GetHeight() {
- return height;
-}
-
-
-
-/// @brief Get FPS
-/// @return
-///
-double DummyVideoProvider::GetFPS() {
- return fps;
-}
-
-
-
-/// @brief Get decoder name
-///
-wxString DummyVideoProvider::GetDecoderName() {
- return L"Dummy Video Provider";
-}
-
-
-
diff --git a/aegisub/src/video_provider_dummy.h b/aegisub/src/video_provider_dummy.h
index 9d4a3d0c4..d57b42a92 100644
--- a/aegisub/src/video_provider_dummy.h
+++ b/aegisub/src/video_provider_dummy.h
@@ -36,18 +36,11 @@
// The dummy video provider needs a header, since it needs to be created directly as a special case
-
-
-
-///////////
-// Headers
#ifndef AGI_PRE
#include
#endif
#include "include/aegisub/video_provider.h"
-#include "vfr.h"
-
/// DOCME
/// @class DummyVideoProvider
@@ -55,8 +48,6 @@
///
/// DOCME
class DummyVideoProvider : public VideoProvider {
-private:
-
/// DOCME
int lastFrame;
@@ -64,7 +55,7 @@ private:
int framecount;
/// DOCME
- double fps;
+ agi::vfr::Framerate fps;
/// DOCME
int width;
@@ -85,37 +76,11 @@ public:
const AegiVideoFrame GetFrame(int n);
static wxString MakeFilename(double fps, int frames, int _width, int _height, const wxColour &colour, bool pattern);
- int GetPosition();
- int GetFrameCount();
-
- int GetWidth();
- int GetHeight();
- double GetFPS();
-
-
- /// @brief DOCME
- /// @return
- ///
- bool AreKeyFramesLoaded() { return false; };
-
- /// @brief DOCME
- /// @return
- ///
- wxArrayInt GetKeyFrames() { return wxArrayInt(); };
-
- /// @brief DOCME
- /// @return
- ///
- bool IsVFR() { return false; };
-
- /// @brief DOCME
- /// @return
- ///
- bool NeedsVFRHack() { return true; }
-
- /// @brief DOCME
- ///
- FrameRate GetTrueFrameRate() { return FrameRate(); };
-
- wxString GetDecoderName();
+ int GetPosition() const { return lastFrame; }
+ int GetFrameCount() const { return framecount; }
+ int GetWidth() const { return width; }
+ int GetHeight() const { return height; }
+ agi::vfr::Framerate GetFPS() const { return fps; }
+ std::vector GetKeyFrames() const { return std::vector(); };
+ wxString GetDecoderName() const { return L"Dummy Video Provider"; }
};
diff --git a/aegisub/src/video_provider_ffmpegsource.cpp b/aegisub/src/video_provider_ffmpegsource.cpp
index 68472d839..91e40f3f6 100644
--- a/aegisub/src/video_provider_ffmpegsource.cpp
+++ b/aegisub/src/video_provider_ffmpegsource.cpp
@@ -38,8 +38,6 @@
#ifdef WITH_FFMPEGSOURCE
-///////////
-// Headers
#ifndef AGI_PRE
#ifdef __WINDOWS__
#include
@@ -79,7 +77,6 @@ FFmpegSourceVideoProvider::FFmpegSourceVideoProvider(wxString filename) {
// clean up variables
VideoSource = NULL;
- KeyFramesLoaded = false;
FrameNumber = -1;
ErrInfo.Buffer = FFMSErrMsg;
ErrInfo.BufferSize = sizeof(FFMSErrMsg);
@@ -197,7 +194,7 @@ void FFmpegSourceVideoProvider::LoadVideo(wxString filename) {
FFMS_DestroyIndex(Index);
Index = NULL;
ErrorMsg.Append(wxString::Format(_T("Couldn't find any video tracks: %s"), ErrInfo.Buffer));
- throw ErrorMsg;
+ throw ErrorMsg;
}
}
@@ -249,6 +246,7 @@ void FFmpegSourceVideoProvider::LoadVideo(wxString filename) {
const FFMS_FrameInfo *CurFrameData;
// build list of keyframes and timecodes
+ std::vector TimecodesVector;
for (int CurFrameNum = 0; CurFrameNum < VideoInfo->NumFrames; CurFrameNum++) {
CurFrameData = FFMS_GetFrameInfo(FrameData, CurFrameNum);
if (CurFrameData == NULL) {
@@ -258,47 +256,29 @@ void FFmpegSourceVideoProvider::LoadVideo(wxString filename) {
// keyframe?
if (CurFrameData->KeyFrame)
- KeyFramesList.Add(CurFrameNum);
+ KeyFramesList.push_back(CurFrameNum);
// calculate timestamp and add to timecodes vector
int Timestamp = (int)((CurFrameData->PTS * TimeBase->Num) / TimeBase->Den);
TimecodesVector.push_back(Timestamp);
}
- KeyFramesLoaded = true;
-
- // override already loaded timecodes?
- Timecodes.SetVFR(TimecodesVector);
- int OverrideTC = wxYES;
- if (VFR_Output.IsLoaded()) {
- OverrideTC = wxMessageBox(_("You already have timecodes loaded. Would you like to replace them with timecodes from the video file?"), _("Replace timecodes?"), wxYES_NO | wxICON_QUESTION);
- if (OverrideTC == wxYES) {
- VFR_Input.SetVFR(TimecodesVector);
- VFR_Output.SetVFR(TimecodesVector);
- }
- } else { // no timecodes loaded, go ahead and apply
- VFR_Input.SetVFR(TimecodesVector);
- VFR_Output.SetVFR(TimecodesVector);
- }
+ Timecodes = agi::vfr::Framerate(TimecodesVector);
FrameNumber = 0;
}
-
/// @brief Close video
///
void FFmpegSourceVideoProvider::Close() {
FFMS_DestroyVideoSource(VideoSource);
VideoSource = NULL;
- KeyFramesLoaded = false;
KeyFramesList.clear();
- TimecodesVector.clear();
FrameNumber = -1;
+ Timecodes = agi::vfr::Framerate();
CurFrame.Clear();
}
-
-
/// @brief Get frame
/// @param _n
/// @return
@@ -323,48 +303,4 @@ const AegiVideoFrame FFmpegSourceVideoProvider::GetFrame(int _n) {
CurFrame.SetTo(SrcFrame->Data, Width, Height, SrcFrame->Linesize, FORMAT_RGB32);
return CurFrame;
}
-
-
-
-/// @brief Utility functions
-/// @return
-///
-int FFmpegSourceVideoProvider::GetWidth() {
- return Width;
-}
-
-
-/// @brief DOCME
-/// @return
-///
-int FFmpegSourceVideoProvider::GetHeight() {
- return Height;
-}
-
-
-/// @brief DOCME
-/// @return
-///
-int FFmpegSourceVideoProvider::GetFrameCount() {
- return VideoInfo->NumFrames;
-}
-
-
-/// @brief DOCME
-/// @return
-///
-int FFmpegSourceVideoProvider::GetPosition() {
- return FrameNumber;
-}
-
-
-/// @brief DOCME
-///
-double FFmpegSourceVideoProvider::GetFPS() {
- return double(VideoInfo->FPSNumerator) / double(VideoInfo->FPSDenominator);
-}
-
-
#endif /* WITH_FFMPEGSOURCE */
-
-
diff --git a/aegisub/src/video_provider_ffmpegsource.h b/aegisub/src/video_provider_ffmpegsource.h
index 9f8ba3721..1ced5e125 100644
--- a/aegisub/src/video_provider_ffmpegsource.h
+++ b/aegisub/src/video_provider_ffmpegsource.h
@@ -34,8 +34,6 @@
/// @ingroup video_input ffms
///
-///////////
-// Headers
#ifdef WITH_FFMPEGSOURCE
#ifndef AGI_PRE
#include
@@ -43,7 +41,6 @@
#include "ffmpegsource_common.h"
#include "include/aegisub/video_provider.h"
-#include "vfr.h"
/// @class FFmpegSourceVideoProvider
@@ -56,10 +53,8 @@ private:
int Width; /// width in pixels
int Height; /// height in pixels
int FrameNumber; /// current framenumber
- wxArrayInt KeyFramesList; /// list of keyframes
- bool KeyFramesLoaded; /// keyframe loading state
- std::vector TimecodesVector; /// list of timestamps
- FrameRate Timecodes; /// vfr object
+ std::vector KeyFramesList; /// list of keyframes
+ agi::vfr::Framerate Timecodes; /// vfr object
bool COMInited; /// COM initialization state
AegiVideoFrame CurFrame; /// current video frame
@@ -76,35 +71,22 @@ public:
~FFmpegSourceVideoProvider();
const AegiVideoFrame GetFrame(int n);
- int GetPosition();
- int GetFrameCount();
- int GetWidth();
- int GetHeight();
- double GetFPS();
+ int GetPosition() const { return FrameNumber; }
+ int GetFrameCount() const { return VideoInfo->NumFrames; }
+ int GetWidth() const { return Width; }
+ int GetHeight() const { return Height; }
+ agi::vfr::Framerate GetFPS() const { return Timecodes; }
- /// @brief Reports keyframe status
- /// @return Returns true if keyframes are loaded, false otherwise.
- bool AreKeyFramesLoaded() { return KeyFramesLoaded; };
/// @brief Gets a list of keyframes
/// @return Returns a wxArrayInt of keyframes.
- wxArrayInt GetKeyFrames() { return KeyFramesList; };
- /// @brief Checks if source is VFR
- /// @return Returns true.
- bool IsVFR() { return true; };
- /// @brief Gets a VFR framerate object
- /// @return Returns the framerate object.
- FrameRate GetTrueFrameRate() { return Timecodes; };
- /// @brief Gets the name of the provider
- /// @return Returns "FFmpegSource".
- wxString GetDecoderName() { return L"FFmpegSource"; }
+ std::vector GetKeyFrames() const { return KeyFramesList; };
+ wxString GetDecoderName() const { return L"FFmpegSource"; }
/// @brief Gets the desired cache behavior.
/// @return Returns true.
- bool WantsCaching() { return true; }
+ bool WantsCaching() const { return true; }
};
-
-
/// @class FFmpegSourceVideoProviderFactory
/// @brief Creates a FFmpegSource video provider.
class FFmpegSourceVideoProviderFactory : public VideoProviderFactory {
@@ -115,7 +97,4 @@ public:
VideoProvider *CreateProvider(wxString video) { return new FFmpegSourceVideoProvider(video); }
};
-
#endif /* WITH_FFMPEGSOURCE */
-
-
diff --git a/aegisub/src/video_provider_manager.cpp b/aegisub/src/video_provider_manager.cpp
index 62220ba91..12766dfbf 100644
--- a/aegisub/src/video_provider_manager.cpp
+++ b/aegisub/src/video_provider_manager.cpp
@@ -34,9 +34,6 @@
/// @ingroup video_input
///
-
-///////////
-// Headers
#include "config.h"
#include
@@ -44,7 +41,7 @@
#include "compat.h"
#include "main.h"
#include "options.h"
-#include "vfr.h"
+
#ifdef WITH_AVISYNTH
#include "video_provider_avs.h"
#endif
diff --git a/aegisub/src/video_provider_quicktime.cpp b/aegisub/src/video_provider_quicktime.cpp
index 55f779a60..60230250e 100644
--- a/aegisub/src/video_provider_quicktime.cpp
+++ b/aegisub/src/video_provider_quicktime.cpp
@@ -54,8 +54,6 @@
#define MacOffsetRect OffsetRect
#endif
-
-
/// @brief DOCME
/// @param filename
///
@@ -99,8 +97,6 @@ QuickTimeVideoProvider::QuickTimeVideoProvider(wxString filename) {
}
}
-
-
/// @brief DOCME
///
QuickTimeVideoProvider::~QuickTimeVideoProvider() {
@@ -108,8 +104,6 @@ QuickTimeVideoProvider::~QuickTimeVideoProvider() {
DeInitQuickTime();
}
-
-
/// @brief DOCME
///
void QuickTimeVideoProvider::Close() {
@@ -123,15 +117,10 @@ void QuickTimeVideoProvider::Close() {
DisposeHandle(in_dataref);
in_dataref = NULL;
- keyframes.Clear();
+ keyframes.clear();
qt_timestamps.clear();
}
-
-
-
-
-
/// @brief DOCME
/// @param _filename
///
@@ -175,28 +164,11 @@ void QuickTimeVideoProvider::LoadVideo(const wxString _filename) {
throw wxString(_T("QuickTime video provider: failed to index file"));
// ask about vfr override etc
- vfr_fps.SetVFR(timecodes);
- int override_tc = wxYES;
- if (VFR_Output.IsLoaded()) {
- override_tc = wxMessageBox(_("You already have timecodes loaded. Would you like to replace them with timecodes from the video file?"), _("Replace timecodes?"), wxYES_NO | wxICON_QUESTION);
- if (override_tc == wxYES) {
- VFR_Input.SetVFR(timecodes);
- VFR_Output.SetVFR(timecodes);
- }
- } else { // no timecodes loaded, go ahead and apply
- VFR_Input.SetVFR(timecodes);
- VFR_Output.SetVFR(timecodes);
- }
-
- // set assumed "cfr" fps (dunno if this is actually used anywhere)
- double len_s = (double)GetMovieDuration(movie) / (double)GetMovieTimeScale(movie);
- assumed_fps = (double)num_frames / len_s;
+ vfr_fps = agi::vfr::Framerate(timecodes);
cur_fn = 0;
}
-
-
/// @brief DOCME
/// @return
///
@@ -237,8 +209,6 @@ std::vector QuickTimeVideoProvider::IndexFile() {
return timecodes;
}
-
-
/// @brief DOCME
/// @param n
/// @return
@@ -283,76 +253,4 @@ const AegiVideoFrame QuickTimeVideoProvider::GetFrame(int n) {
return dst_frame;
}
-
-
-
-
-/// @brief Utility functions
-/// @return
-///
-int QuickTimeVideoProvider::GetWidth() {
- return w;
-}
-
-
-/// @brief DOCME
-/// @return
-///
-int QuickTimeVideoProvider::GetHeight() {
- return h;
-}
-
-
-/// @brief DOCME
-/// @return
-///
-int QuickTimeVideoProvider::GetFrameCount() {
- return num_frames;
-}
-
-
-/// @brief DOCME
-/// @return
-///
-int QuickTimeVideoProvider::GetPosition() {
- return cur_fn;
-}
-
-
-/// @brief DOCME
-/// @return
-///
-double QuickTimeVideoProvider::GetFPS() {
- return assumed_fps;
-}
-
-
-/// @brief DOCME
-/// @return
-///
-bool QuickTimeVideoProvider::AreKeyFramesLoaded() {
- if (keyframes.GetCount() > 0)
- return true;
- else
- return false;
-}
-
-
-/// @brief DOCME
-/// @return
-///
-wxArrayInt QuickTimeVideoProvider::GetKeyFrames() {
- return keyframes;
-}
-
-
-/// @brief DOCME
-///
-FrameRate QuickTimeVideoProvider::GetTrueFrameRate() {
- return vfr_fps;
-}
-
-
#endif /* WITH_QUICKTIME */
-
-
diff --git a/aegisub/src/video_provider_quicktime.h b/aegisub/src/video_provider_quicktime.h
index 2a8b45d9a..a8eb40fd1 100644
--- a/aegisub/src/video_provider_quicktime.h
+++ b/aegisub/src/video_provider_quicktime.h
@@ -49,8 +49,6 @@
#include "include/aegisub/video_provider.h"
-#include "vfr.h"
-
/// DOCME
/// @class QuickTimeVideoProvider
@@ -58,47 +56,42 @@
///
/// DOCME
class QuickTimeVideoProvider : public VideoProvider, QuickTimeProvider {
-private:
+ /// source object
+ Movie movie;
- /// DOCME
- Movie movie; // source object
+ /// render buffer
+ GWorldPtr gw;
- /// DOCME
- GWorldPtr gw; // render buffer
-
- /// DOCME
- Handle in_dataref; // input data handle
+ /// input data handle
+ Handle in_dataref;
/// DOCME
- /// DOCME
- int w, h; // width/height
+ /// width/height
+ int w, h;
- /// DOCME
- int num_frames; // length of file in frames
+ /// length of file in frames
+ int num_frames;
- /// DOCME
- int cur_fn; // current frame number
+ /// current frame number
+ int cur_fn;
- /// DOCME
- FrameRate vfr_fps; // vfr framerate
+ /// vfr framerate
+ Framerate vfr_fps;
- /// DOCME
- double assumed_fps; // average framerate
+ /// list of keyframes
+ std::vector keyframes;
- /// DOCME
- wxArrayInt keyframes; // list of keyframes
-
- /// DOCME
- std::vector qt_timestamps; // qt timestamps (used for seeking)
+ /// qt timestamps (used for seeking)
+ std::vector qt_timestamps;
- /// DOCME
- OSErr qt_err; // quicktime error code
+ /// quicktime error code
+ OSErr qt_err;
- /// DOCME
- wxString errmsg; // aegisub error message
+ /// aegisub error message
+ wxString errmsg;
void LoadVideo(const wxString filename);
std::vector IndexFile();
@@ -109,34 +102,18 @@ public:
~QuickTimeVideoProvider();
const AegiVideoFrame GetFrame(int n);
- int GetPosition();
- int GetFrameCount();
- int GetWidth();
- int GetHeight();
- double GetFPS();
-
- /// @brief DOCME
- /// @return
- ///
- bool IsVFR() { return true; };
- FrameRate GetTrueFrameRate();
- wxArrayInt GetKeyFrames();
- bool QuickTimeVideoProvider::AreKeyFramesLoaded();
-
- /// @brief DOCME
- /// @return
- ///
- wxString GetDecoderName() { return L"QuickTime"; };
-
- /// @brief DOCME
- /// @return
- ///
- bool WantsCaching() { return true; };
+ int GetPosition() const { return cur_fn; }
+ int GetFrameCount() const { return num_frames; }
+ int GetWidth() const { return w; }
+ int GetHeight() const { return h; }
+ agi::vfr::Framerate GetFPS() const { return vfr_fps; }
+ std::vector GetKeyFrames() const { return keyframes; };
+ wxString GetDecoderName() const { return L"QuickTime"; };
+ bool WantsCaching() const { return true; };
+ wxString GetWarning() const { return errmsg; }
};
-
-
/// DOCME
/// @class QuickTimeVideoProviderFactory
/// @brief DOCME
@@ -151,7 +128,4 @@ public:
VideoProvider *CreateProvider(wxString video) { return new QuickTimeVideoProvider(video); }
};
-
#endif /* WITH_QUICKTIME */
-
-
diff --git a/aegisub/src/video_provider_yuv4mpeg.cpp b/aegisub/src/video_provider_yuv4mpeg.cpp
index 5d7af1785..02ac91b34 100644
--- a/aegisub/src/video_provider_yuv4mpeg.cpp
+++ b/aegisub/src/video_provider_yuv4mpeg.cpp
@@ -309,6 +309,7 @@ void YUV4MPEGVideoProvider::ParseFileHeader(const std::vector& tags) {
fps_rat.den = t_fps_den;
pixfmt = t_pixfmt != Y4M_PIXFMT_NONE ? t_pixfmt : Y4M_PIXFMT_420JPEG;
imode = t_imode != Y4M_ILACE_NOTSET ? t_imode : Y4M_ILACE_UNKNOWN;
+ fps = double(fps_rat.num) / fps_rat.den;
inited = true;
}
}
@@ -430,27 +431,3 @@ const AegiVideoFrame YUV4MPEGVideoProvider::GetFrame(int n) {
return dst_frame;
}
-
-
-
-// Utility functions
-int YUV4MPEGVideoProvider::GetWidth() {
- return w;
-}
-
-int YUV4MPEGVideoProvider::GetHeight() {
- return h;
-}
-
-int YUV4MPEGVideoProvider::GetFrameCount() {
- return num_frames;
-}
-
-int YUV4MPEGVideoProvider::GetPosition() {
- return cur_fn;
-}
-
-double YUV4MPEGVideoProvider::GetFPS() {
- return double(fps_rat.num) / double(fps_rat.den);
-}
-
diff --git a/aegisub/src/video_provider_yuv4mpeg.h b/aegisub/src/video_provider_yuv4mpeg.h
index 33a178049..9a59e613c 100644
--- a/aegisub/src/video_provider_yuv4mpeg.h
+++ b/aegisub/src/video_provider_yuv4mpeg.h
@@ -34,8 +34,6 @@
/// @ingroup video_input
///
-
-
#include "include/aegisub/video_provider.h"
#ifndef AGI_PRE
#include
@@ -46,16 +44,12 @@
#include
#endif
-
/// the maximum allowed header length, in bytes
#define YUV4MPEG_HEADER_MAXLEN 128
-
-
/// @class YUV4MPEGVideoProvider
/// @brief Implements reading of YUV4MPEG uncompressed video files
class YUV4MPEGVideoProvider : public VideoProvider {
-private:
/// Pixel formats
enum Y4M_PixelFormat {
Y4M_PIXFMT_NONE = -1, /// not set/unknown
@@ -131,6 +125,8 @@ private:
int den; /// denominator
} fps_rat; /// framerate
+ agi::vfr::Framerate fps;
+
/// a list of byte positions detailing where in the file
/// each frame header can be found
std::vector seek_table;
@@ -151,20 +147,13 @@ public:
~YUV4MPEGVideoProvider();
const AegiVideoFrame GetFrame(int n);
- int GetPosition();
- int GetFrameCount();
- int GetWidth();
- int GetHeight();
- double GetFPS();
-
- bool AreKeyFramesLoaded() { return false; }
- wxArrayInt GetKeyFrames() { return wxArrayInt(); }
- bool IsVFR() { return false; };
- FrameRate GetTrueFrameRate() { return FrameRate(); }
- wxString GetDecoderName() { return L"YUV4MPEG"; }
- bool WantsCaching() { return true; }
+ int GetPosition() const { return cur_fn; }
+ int GetFrameCount() const { return num_frames; }
+ int GetWidth() const { return w; }
+ int GetHeight() const { return h; }
+ agi::vfr::Framerate GetFPS() const { return fps; }
+ std::vector GetKeyFrames() const { return std::vector(); };
+ wxString GetDecoderName() const { return L"YU4MPEG"; };
+ bool WantsCaching() const { return true; };
};
-
-
-
diff --git a/aegisub/src/video_slider.cpp b/aegisub/src/video_slider.cpp
index 9725a8a85..bb0f2477f 100644
--- a/aegisub/src/video_slider.cpp
+++ b/aegisub/src/video_slider.cpp
@@ -49,7 +49,6 @@
#include "subs_edit_box.h"
#include "subs_grid.h"
#include "utils.h"
-#include "vfr.h"
#include "video_context.h"
#include "video_display.h"
#include "video_slider.h"
@@ -226,8 +225,8 @@ void VideoSlider::OnMouse(wxMouseEvent &event) {
if (canDrag) {
// Shift click to snap to keyframe
if (shift && Display) {
- wxArrayInt KeyFrames = VideoContext::Get()->GetKeyFrames();
- int keys = KeyFrames.Count();
+ std::vector KeyFrames = VideoContext::Get()->GetKeyFrames();
+ int keys = KeyFrames.size();
int clickedFrame = GetValueAtX(x);
int closest = 0;
int cur;
@@ -332,8 +331,8 @@ void VideoSlider::OnKeyDown(wxKeyEvent &event) {
// Jump to next sub boundary
if (direction != 0) {
- int target1 = VFR_Output.GetFrameAtTime(curDiag->Start.GetMS(),true);
- int target2 = VFR_Output.GetFrameAtTime(curDiag->End.GetMS(),false);
+ int target1 = VideoContext::Get()->FrameAtTime(curDiag->Start.GetMS(),agi::vfr::START);
+ int target2 = VideoContext::Get()->FrameAtTime(curDiag->End.GetMS(),agi::vfr::END);
bool drawn = false;
// Forward
@@ -376,8 +375,8 @@ void VideoSlider::OnKeyDown(wxKeyEvent &event) {
// Prepare
int prevKey = 0;
int nextKey = VideoContext::Get()->GetLength()-1;
- wxArrayInt KeyFrames = VideoContext::Get()->GetKeyFrames();
- int keys = KeyFrames.Count();
+ std::vector KeyFrames = VideoContext::Get()->GetKeyFrames();
+ int keys = KeyFrames.size();
int cur = VideoContext::Get()->GetFrameN();
int i;
int temp;
@@ -481,8 +480,8 @@ void VideoSlider::DrawImage(wxDC &destdc) {
int curX;
if (Display && OPT_GET("Video/Slider/Show Keyframes")->GetBool()) {
dc.SetPen(wxPen(shad));
- wxArrayInt KeyFrames = VideoContext::Get()->GetKeyFrames();
- int keys = KeyFrames.Count();
+ std::vector KeyFrames = VideoContext::Get()->GetKeyFrames();
+ int keys = KeyFrames.size();
for (int i=0;itype != DRAG_ORIGIN) {
- int time = VFR_Output.GetTimeAtFrame(frameNumber,true,true) - feature->line->Start.GetMS();
+ int time = VideoContext::Get()->TimeAtFrame(frameNumber) - feature->line->Start.GetMS();
int change = time - feature->time;
for (sel_iterator cur = selectedFeatures.begin(); cur != selectedFeatures.end(); ++cur) {