Added support for reading keyframes from xvid pass files
Originally committed to SVN as r1535.
This commit is contained in:
parent
4f689ac204
commit
3518f381a7
7 changed files with 222 additions and 101 deletions
|
@ -175,6 +175,7 @@ aegisub_SOURCES = \
|
|||
hotkeys.cpp \
|
||||
idle_field_event.cpp \
|
||||
kana_table.cpp \
|
||||
keyframe.cpp \
|
||||
main.cpp \
|
||||
md5.c \
|
||||
mkv_wrap.cpp \
|
||||
|
|
|
@ -153,7 +153,7 @@ Please visit http://aegisub.net to download latest version
|
|||
- Frame number is now the default box on the "go to" dialog. (AMZ)
|
||||
- Added "Video Formats" to "Open Audio"'s file selector, so you can open audio directly from video files (regardless of whether they're loaded or not). This has always worked, but it was never explicit. (AMZ)
|
||||
- Added a "Scale Border and Shadow" check box to script properties dialog. (AMZ)
|
||||
- Fixed display of end frames on the subtitles grid, when set to frame mode. (demi)
|
||||
- Fixed display of end frames on the subtitles grid, when set to frame mode. (demi`)
|
||||
- Treat comments inside {}'s as plain text, not as overrides; Also, don't assume override blocks start with a backslash, even if they probably should (Dansolo)
|
||||
- Removed FexTracker due to licensing problems; there are plans to implement a new motion tracker in its place (jfs)
|
||||
- Changed translation assistent to use Scintilla text controls to avoid several issues, including Right-To-Left text entry. (AMZ)
|
||||
|
@ -161,6 +161,7 @@ Please visit http://aegisub.net to download latest version
|
|||
- Added a "new window" command to the file menu, to launch a new instance of Aegisub. (AMZ)
|
||||
- Added "Effect" field to the Select Lines dialog. (demi`)
|
||||
- Added a new "Video Details" dialog, that lists some information regarding the currently open video. (demi`)
|
||||
- Added support for reading keyframes from xvid pass files. (demi`)
|
||||
|
||||
|
||||
= 1.10 beta - 2006.08.07 ===========================
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
#include "dialog_version_check.h"
|
||||
#include "dialog_detached_video.h"
|
||||
#include "standard_paths.h"
|
||||
#include "keyframe.h"
|
||||
|
||||
|
||||
/////////////////////////
|
||||
|
@ -836,7 +837,7 @@ void FrameMain::SynchronizeProject(bool fromSubs) {
|
|||
}
|
||||
|
||||
// Keyframes
|
||||
LoadKeyframes(curSubsKeyframes);
|
||||
KeyFrameFile::Load(curSubsKeyframes);
|
||||
|
||||
// Audio
|
||||
if (curSubsAudio != audioBox->audioName) {
|
||||
|
@ -1057,98 +1058,6 @@ void FrameMain::LoadVFR(wxString filename) {
|
|||
}
|
||||
|
||||
|
||||
//////////////////
|
||||
// Load Keyframes
|
||||
void FrameMain::LoadKeyframes(wxString filename) {
|
||||
// Unload
|
||||
if (filename.IsEmpty()) {
|
||||
wxArrayInt keyFrames;
|
||||
keyFrames.Empty();
|
||||
VideoContext::Get()->CloseOverKeyFrames();
|
||||
videoBox->videoSlider->Refresh();
|
||||
audioBox->audioDisplay->Update();
|
||||
Refresh();
|
||||
return;
|
||||
}
|
||||
|
||||
// Load
|
||||
try {
|
||||
// Open file
|
||||
wxArrayInt keyFrames;
|
||||
keyFrames.Empty();
|
||||
TextFileReader file(filename,_T("ASCII"));
|
||||
|
||||
// Read header
|
||||
wxString cur = file.ReadLineFromFile();
|
||||
if (cur != _T("# keyframe format v1")) throw _T("Invalid keyframes file, missing header.");
|
||||
cur = file.ReadLineFromFile();
|
||||
if (cur.Left(4) != _T("fps ")) throw _T("Invalid keyframes file, missing FPS.");
|
||||
cur = cur.Mid(4);
|
||||
double fps;
|
||||
cur.ToDouble(&fps);
|
||||
if (fps == 0.0) throw _T("Invalid FPS.");
|
||||
|
||||
// Read lines
|
||||
while (file.HasMoreLines()) {
|
||||
cur = file.ReadLineFromFile();
|
||||
if (!cur.IsEmpty() && cur.IsNumber()) {
|
||||
long temp;
|
||||
cur.ToLong(&temp);
|
||||
keyFrames.Add(temp);
|
||||
}
|
||||
}
|
||||
|
||||
// Set keyframes
|
||||
VideoContext::Get()->SetOverKeyFrames(keyFrames);
|
||||
VideoContext::Get()->SetKeyFramesName(filename);
|
||||
|
||||
// Set FPS
|
||||
if (!VideoContext::Get()->IsLoaded()) {
|
||||
VideoContext::Get()->SetFPS(fps);
|
||||
VFR_Input.SetCFR(fps);
|
||||
if (!VFR_Output.IsLoaded()) VFR_Output.SetCFR(fps);
|
||||
}
|
||||
|
||||
// Add to recent
|
||||
Options.AddToRecentList(filename,_T("Recent keyframes"));
|
||||
|
||||
// Refresh display
|
||||
Refresh();
|
||||
audioBox->audioDisplay->Update();
|
||||
}
|
||||
|
||||
// Fail
|
||||
catch (const wchar_t *error) {
|
||||
wxString err(error);
|
||||
wxMessageBox(err, _T("Error opening keyframes file"), wxOK | wxICON_ERROR, this);
|
||||
}
|
||||
catch (...) {
|
||||
wxMessageBox(_T("Unknown error"), _T("Error opening keyframes file"), wxOK | wxICON_ERROR, this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////
|
||||
// Save Keyframes
|
||||
void FrameMain::SaveKeyframes(wxString filename) {
|
||||
// Get keyframes
|
||||
wxArrayInt keyFrames = VideoContext::Get()->GetKeyFrames();
|
||||
|
||||
// Write header
|
||||
TextFileWriter file(filename,_T("ASCII"));
|
||||
file.WriteLineToFile(_T("# keyframe format v1"));
|
||||
file.WriteLineToFile(wxString::Format(_T("fps %f"),VideoContext::Get()->GetFPS()));
|
||||
|
||||
// Write keyframes
|
||||
for (unsigned int i=0;i<keyFrames.Count();i++) {
|
||||
file.WriteLineToFile(wxString::Format(_T("%i"),keyFrames[i]));
|
||||
}
|
||||
|
||||
// Add to recent
|
||||
Options.AddToRecentList(filename,_T("Recent keyframes"));
|
||||
}
|
||||
|
||||
|
||||
/////////////
|
||||
// Open help
|
||||
void FrameMain::OpenHelp(wxString page) {
|
||||
|
|
|
@ -242,8 +242,6 @@ private:
|
|||
void LoadVideo(wxString filename,bool autoload=false);
|
||||
void LoadAudio(wxString filename,bool FromVideo=false);
|
||||
void LoadVFR(wxString filename);
|
||||
void LoadKeyframes(wxString filename);
|
||||
void SaveKeyframes(wxString filename);
|
||||
void LoadSubtitles(wxString filename,wxString charset=_T(""));
|
||||
bool SaveSubtitles(bool saveas=false,bool withCharset=false);
|
||||
int TryToCloseSubs(bool enableCancel=true);
|
||||
|
|
|
@ -84,6 +84,7 @@
|
|||
#include "dialog_associations.h"
|
||||
#include "standard_paths.h"
|
||||
#include "dialog_video_details.h"
|
||||
#include "keyframe.h"
|
||||
|
||||
|
||||
////////////////////
|
||||
|
@ -500,7 +501,10 @@ void FrameMain::OnOpenRecentTimecodes(wxCommandEvent &event) {
|
|||
void FrameMain::OnOpenRecentKeyframes(wxCommandEvent &event) {
|
||||
int number = event.GetId()-Menu_Keyframes_Recent;
|
||||
wxString key = _T("Recent Keyframes #") + wxString::Format(_T("%i"),number+1);
|
||||
LoadKeyframes(Options.AsText(key));
|
||||
KeyFrameFile::Load(Options.AsText(key));
|
||||
videoBox->videoSlider->Refresh();
|
||||
audioBox->audioDisplay->Update();
|
||||
Refresh();
|
||||
}
|
||||
|
||||
|
||||
|
@ -759,20 +763,26 @@ void FrameMain::OnCloseVFR(wxCommandEvent &event) {
|
|||
void FrameMain::OnOpenKeyframes (wxCommandEvent &event) {
|
||||
// Pick file
|
||||
wxString path = Options.AsText(_T("Last open keyframes path"));
|
||||
wxString filename = wxFileSelector(_T("Select the Keyframes file to open"),path,_T(""),_T(".txt"),_T("Text files (*.txt)|*.txt"),wxFD_FILE_MUST_EXIST | wxFD_OPEN);
|
||||
wxString filename = wxFileSelector(_T("Select the keyframes file to open"),path,_T(""),_T(".txt"),_T("All supported formats (*.txt, *.pass)|*.txt;*.pass|All files (*.*)|*.*"),wxFD_FILE_MUST_EXIST | wxFD_OPEN);
|
||||
if (filename.IsEmpty()) return;
|
||||
Options.SetText(_T("Last open keyframes path"),filename);
|
||||
Options.Save();
|
||||
|
||||
// Load
|
||||
LoadKeyframes(filename);
|
||||
KeyFrameFile::Load(filename);
|
||||
videoBox->videoSlider->Refresh();
|
||||
audioBox->audioDisplay->Update();
|
||||
Refresh();
|
||||
}
|
||||
|
||||
|
||||
///////////////////
|
||||
// Close keyframes
|
||||
void FrameMain::OnCloseKeyframes (wxCommandEvent &event) {
|
||||
LoadKeyframes(_T(""));
|
||||
VideoContext::Get()->CloseOverKeyFrames();
|
||||
videoBox->videoSlider->Refresh();
|
||||
audioBox->audioDisplay->Update();
|
||||
Refresh();
|
||||
}
|
||||
|
||||
|
||||
|
@ -787,7 +797,7 @@ void FrameMain::OnSaveKeyframes (wxCommandEvent &event) {
|
|||
Options.Save();
|
||||
|
||||
// Save
|
||||
SaveKeyframes(filename);
|
||||
KeyFrameFile::Save(filename);
|
||||
}
|
||||
|
||||
|
||||
|
|
150
aegisub/keyframe.cpp
Normal file
150
aegisub/keyframe.cpp
Normal file
|
@ -0,0 +1,150 @@
|
|||
// Copyright (c) 2007, Alysson Souza e Silva
|
||||
// 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
|
||||
//
|
||||
// Website: http://aegisub.cellosoft.com
|
||||
// Contact: mailto:zeratul@cellosoft.com
|
||||
//
|
||||
|
||||
///////////
|
||||
// Headers
|
||||
#include "video_context.h"
|
||||
#include "keyframe.h"
|
||||
#include "text_file_reader.h"
|
||||
#include "text_file_writer.h"
|
||||
#include "options.h"
|
||||
#include "vfr.h"
|
||||
|
||||
|
||||
//////////////////
|
||||
// Load Keyframes
|
||||
void KeyFrameFile::Load(wxString filename) {
|
||||
// Load
|
||||
try {
|
||||
// Open file
|
||||
wxArrayInt keyFrames;
|
||||
keyFrames.Empty();
|
||||
TextFileReader file(filename,_T("ASCII"));
|
||||
|
||||
wxString cur = file.ReadLineFromFile();
|
||||
// Detect type
|
||||
if (cur == _T("# keyframe format v1")) { OpenAegiKeyFrames(file, keyFrames); }
|
||||
else if (cur.StartsWith(_T("# XviD 2pass stat file"))) { OpenXviDKeyFrames(file, keyFrames); }
|
||||
else { throw(_T("Invalid keyframes file.")); }
|
||||
|
||||
// Set keyframes
|
||||
VideoContext::Get()->SetOverKeyFrames(keyFrames);
|
||||
VideoContext::Get()->SetKeyFramesName(filename);
|
||||
|
||||
// Add to recent
|
||||
Options.AddToRecentList(filename,_T("Recent keyframes"));
|
||||
}
|
||||
// Fail
|
||||
catch (const wchar_t *error) {
|
||||
wxString err(error);
|
||||
wxMessageBox(err, _T("Error opening keyframes file"), wxOK | wxICON_ERROR, NULL);
|
||||
}
|
||||
catch (...) {
|
||||
wxMessageBox(_T("Unknown error"), _T("Error opening keyframes file"), wxOK | wxICON_ERROR, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////
|
||||
// Save Keyframes
|
||||
void KeyFrameFile::Save(wxString filename) {
|
||||
// Get keyframes
|
||||
wxArrayInt keyFrames = VideoContext::Get()->GetKeyFrames();
|
||||
|
||||
// Write header
|
||||
TextFileWriter file(filename,_T("ASCII"));
|
||||
file.WriteLineToFile(_T("# keyframe format v1"));
|
||||
file.WriteLineToFile(wxString::Format(_T("fps %f"),VideoContext::Get()->GetFPS()));
|
||||
|
||||
// Write keyframes
|
||||
for (unsigned int i=0;i<keyFrames.Count();i++) {
|
||||
file.WriteLineToFile(wxString::Format(_T("%i"),keyFrames[i]));
|
||||
}
|
||||
|
||||
// Add to recent
|
||||
Options.AddToRecentList(filename,_T("Recent keyframes"));
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////
|
||||
// Aegisub keyframes file
|
||||
void KeyFrameFile::OpenAegiKeyFrames(TextFileReader& file, wxArrayInt& keyFrames)
|
||||
{
|
||||
double fps;
|
||||
wxString cur = file.ReadLineFromFile();
|
||||
|
||||
// Read header
|
||||
if (cur.Left(4) != _T("fps ")) throw _T("Invalid keyframes file, missing FPS.");
|
||||
cur = cur.Mid(4);
|
||||
cur.ToDouble(&fps);
|
||||
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);
|
||||
}
|
||||
|
||||
// Read lines
|
||||
while (file.HasMoreLines()) {
|
||||
cur = file.ReadLineFromFile();
|
||||
if (!cur.IsEmpty() && cur.StartsWith(_T("#")) && cur.IsNumber()) {
|
||||
long temp;
|
||||
cur.ToLong(&temp);
|
||||
keyFrames.Add(temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////
|
||||
// XviD stats file
|
||||
void KeyFrameFile::OpenXviDKeyFrames(TextFileReader& file, wxArrayInt& keyFrames)
|
||||
{
|
||||
wxString cur = file.ReadLineFromFile();
|
||||
int count = 0;
|
||||
|
||||
// Read lines
|
||||
while (file.HasMoreLines()) {
|
||||
cur = file.ReadLineFromFile();
|
||||
wxString teste = cur.Left(1);
|
||||
if (cur.StartsWith(_T("i"))) {
|
||||
keyFrames.Add(count);
|
||||
}
|
||||
if (cur.StartsWith(_T("i")) || cur.StartsWith(_T("p")) || cur.StartsWith(_T("b"))) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
52
aegisub/keyframe.h
Normal file
52
aegisub/keyframe.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
// Copyright (c) 2007, Alysson Souza e Silva
|
||||
// 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
|
||||
//
|
||||
// Website: http://aegisub.cellosoft.com
|
||||
// Contact: mailto:zeratul@cellosoft.com
|
||||
//
|
||||
|
||||
|
||||
///////////
|
||||
// Headers
|
||||
#include "text_file_reader.h"
|
||||
|
||||
|
||||
/////////
|
||||
// Class
|
||||
class KeyFrameFile
|
||||
{
|
||||
public:
|
||||
static void Load(wxString filename);
|
||||
static void Save(wxString filename);
|
||||
private:
|
||||
static void OpenAegiKeyFrames(TextFileReader& file, wxArrayInt& keyFrames);
|
||||
static void OpenXviDKeyFrames(TextFileReader& file, wxArrayInt& keyFrames);
|
||||
};
|
Loading…
Reference in a new issue