Rewrite VFR handling in Aegisub.

Kill vfr.h and vfr.cpp and use the libaegisub versions of them instead.

Rather than the globals VFR_Input and VFR_Output, everything related to
frame rate is now part of the video context. Most things which used to
use VFR_Output now call VideoContext::TimeAtFrame etc.; video providers,
rather than modifying VFR_Input directly, now have getters for their
frame rates which VideoContext calls. Read-only public access to
VFR_Input and VFR_Output are still provided (hopefully temporarily) for
a few things which were awkward to do through VideoContext.

The Avisynth provider now might correctly handle VFR MKVs which can be
opened with DirectShowSource but not DSS2.

Rework keyframe handling as well, so that it continues to match the vfr
handling in design and implementation.

Originally committed to SVN as r4662.
This commit is contained in:
Thomas Goyne 2010-07-08 04:29:04 +00:00
parent 9322f95071
commit acba2c6b63
62 changed files with 680 additions and 2616 deletions

View file

@ -1011,14 +1011,6 @@
RelativePath="..\..\src\vector2d.h"
>
</File>
<File
RelativePath="..\..\src\vfr.cpp"
>
</File>
<File
RelativePath="..\..\src\vfr.h"
>
</File>
</Filter>
<Filter
Name="Dialogs"

View file

@ -181,7 +181,7 @@ Framerate::Framerate(std::vector<int> 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<ifstream> 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<int>(*file, encoding), line_iterator<int>(), 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 ") {

View file

@ -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;
};
}

View file

@ -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 \

View file

@ -45,7 +45,6 @@
#include "ass_dialogue.h"
#include "ass_override.h"
#include "utils.h"
#include "vfr.h"
AssDialogue::AssDialogue()
: Comment(false)

View file

@ -60,7 +60,6 @@
#include "text_file_writer.h"
#include "utils.h"
#include "version.h"
#include "vfr.h"
/// @brief AssFile constructor
AssFile::AssFile () {

View file

@ -50,7 +50,6 @@
#include "ass_time.h"
#include "utils.h"
#include "vfr.h"
/// @brief AssTime constructors

View file

@ -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<int> 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<nKeys;i++) {
int cur = KeyFrames[i];
if (cur >= 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<int> keyFrames = VideoContext::Get()->GetKeyFrames();
int frame;
for (unsigned int i=0;i<keyFrames.Count();i++) {
for (unsigned int i=0;i<keyFrames.size();i++) {
frame = keyFrames[i];
if (!start) frame--;
if (frame < 0) frame = 0;
keyMS = VFR_Output.GetTimeAtFrame(frame,start);
keyMS = VideoContext::Get()->TimeAtFrame(frame,start ? agi::vfr::START : agi::vfr::END);
//if (start) keyX++;
if (GetXAtMS(keyMS) >= 0 && GetXAtMS(keyMS) < w) boundaries.Add(keyMS);
}

View file

@ -34,12 +34,8 @@
/// @ingroup audio_ui
///
#pragma once
///////////
// Headers
#ifndef AGI_PRE
#include <stdint.h>
@ -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
};

View file

@ -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);

View file

@ -53,6 +53,7 @@
#endif
class wxWindow;
namespace agi { namespace vfr { class Framerate; } }
/// DOCME

View file

@ -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();
}

View file

@ -37,8 +37,6 @@
#pragma once
////////////
// Includes
#ifndef AGI_PRE
#include <list>
#include <vector>
@ -49,13 +47,11 @@
#include "selection_controller.h"
//////////////
// Prototypes
class AssEntry;
class AssDialogue;
class SubsEditBox;
class FrameMain;
class VideoContext;
/// DOCME
typedef std::list<AssEntry*>::iterator entryIter;
@ -71,8 +67,6 @@ typedef SelectionListener<AssDialogue> SubtitleSelectionListener;
///
/// DOCME
class BaseGrid : public wxWindow, public BaseSelectionController<AssDialogue> {
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
///

View file

@ -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();
}

View file

@ -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"));

View file

@ -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;i<len;i++) {
StyleList->Check(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;i<len;i++) {
StyleList->Check(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;i<n;i++) {
if (abs(KeyFrames[i]-frame) < abs(closest-frame)) {
closest = KeyFrames[i];
@ -358,8 +327,6 @@ int DialogTimingProcessor::GetClosestKeyFrame(int frame) {
return closest;
}
/// @brief Check if style is listed
/// @param styleName
/// @return
@ -372,9 +339,7 @@ bool DialogTimingProcessor::StyleOK(wxString styleName) {
return false;
}
/// @brief Sort dialogues
/// @brief Sort dialogues
///
void DialogTimingProcessor::SortDialogues() {
// Copy from original to temporary list
@ -400,8 +365,6 @@ void DialogTimingProcessor::SortDialogues() {
}
}
/// @brief Gets sorted dialogue
/// @param n
/// @return
@ -415,12 +378,9 @@ AssDialogue *DialogTimingProcessor::GetSortedDialogue(int n) {
}
}
/// @brief Actually process subtitles
///
void DialogTimingProcessor::Process() {
// Sort rows
SortDialogues();
int rows = Sorted.size();
@ -539,8 +499,9 @@ void DialogTimingProcessor::Process() {
// Keyframe snapping
if (keysEnable->IsChecked()) {
// 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();
}

View file

@ -34,11 +34,6 @@
/// @ingroup tools_ui
///
///////////
// Headers
#ifndef AGI_PRE
#include <vector>
@ -51,33 +46,24 @@
#include <wx/textctrl.h>
#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<int> 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<AssDialogue*> 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
};

View file

@ -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);

View file

@ -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<AssDialogue*>(*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;
}

View file

@ -35,7 +35,7 @@
///
#include "ass_export_filter.h"
#include "vfr.h"
#include <libaegisub/vfr.h>
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

View file

@ -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<AssDialogue*>(*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;

View file

@ -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();
}