Rewrite keyframe loading and saving code and move it to libaegisub
Originally committed to SVN as r5073.
This commit is contained in:
parent
ea93f6afba
commit
edff7d6a2d
12 changed files with 186 additions and 257 deletions
|
@ -1361,14 +1361,6 @@
|
|||
<Filter
|
||||
Name="Video backend"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\keyframe.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\keyframe.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\threaded_frame_source.cpp"
|
||||
>
|
||||
|
|
|
@ -275,6 +275,10 @@
|
|||
RelativePath="..\..\libaegisub\common\charset_ucd.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\libaegisub\common\keyframe.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\libaegisub\common\log.cpp"
|
||||
>
|
||||
|
@ -421,6 +425,10 @@
|
|||
RelativePath="..\..\libaegisub\include\libaegisub\io.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\libaegisub\include\libaegisub\keyframe.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\libaegisub\include\libaegisub\line_iterator.h"
|
||||
>
|
||||
|
|
|
@ -24,6 +24,7 @@ SRC = \
|
|||
common/mru.cpp \
|
||||
common/option.cpp \
|
||||
common/option_visit.cpp \
|
||||
common/keyframe.cpp \
|
||||
common/log.cpp \
|
||||
common/validator.cpp \
|
||||
common/vfr.cpp \
|
||||
|
|
117
aegisub/libaegisub/common/keyframe.cpp
Normal file
117
aegisub/libaegisub/common/keyframe.cpp
Normal file
|
@ -0,0 +1,117 @@
|
|||
// Copyright (c) 2011, Thomas Goyne <plorkyeran@aegisub.org>
|
||||
//
|
||||
// Permission to use, copy, modify, and distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
/// @file keyframe.cpp
|
||||
/// @see keyframe.h
|
||||
/// @ingroup libaegisub
|
||||
///
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef LAGI_PRE
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#endif
|
||||
|
||||
#include "libaegisub/io.h"
|
||||
#include "libaegisub/line_iterator.h"
|
||||
#include "libaegisub/keyframe.h"
|
||||
#include "libaegisub/vfr.h"
|
||||
|
||||
static std::pair<std::vector<int>, double> agi_keyframes(std::istream &file) {
|
||||
double fps;
|
||||
std::string fps_str;
|
||||
file >> fps_str;
|
||||
file >> fps;
|
||||
|
||||
if (!file.good() || fps_str != "fps")
|
||||
throw agi::keyframe::Error("FPS not found");
|
||||
|
||||
std::vector<int> ret;
|
||||
std::copy(std::istream_iterator<int>(file), std::istream_iterator<int>(), std::back_inserter(ret));
|
||||
return make_pair(ret, fps);
|
||||
}
|
||||
|
||||
static std::pair<std::vector<int>, double> other_keyframes(std::istream &file, char (*func)(std::string const&)) {
|
||||
int count = 0;
|
||||
std::vector<int> ret;
|
||||
agi::line_iterator<std::string> end;
|
||||
for (agi::line_iterator<std::string> iter(file); iter != end; ++iter) {
|
||||
char c = tolower(func(*iter));
|
||||
if (c == 'i') {
|
||||
ret.push_back(count++);
|
||||
}
|
||||
else if (c == 'p' || c == 'b') {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
return std::make_pair(ret, 0);
|
||||
}
|
||||
|
||||
char xvid(std::string const& line) {
|
||||
return line.empty() ? 0 : line[0];
|
||||
}
|
||||
|
||||
char divx(std::string const& line) {
|
||||
char chrs[] = "IPB";
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
std::string::size_type pos = line.find(chrs[i]);
|
||||
if (pos != line.npos)
|
||||
return line[pos];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char x264(std::string const& line) {
|
||||
std::string::size_type pos = line.find("type:");
|
||||
if (pos == line.npos || pos + 5 >= line.size()) return 0;
|
||||
return line[pos + 5];
|
||||
}
|
||||
|
||||
template<int N>
|
||||
static bool starts_with(std::string const& str, const char (&test)[N]) {
|
||||
if (str.size() < N) return false;
|
||||
return std::mismatch(str.begin(), str.begin() + N - 1, test).first == str.begin() + N - 1;
|
||||
}
|
||||
|
||||
|
||||
namespace agi { namespace keyframe {
|
||||
|
||||
void Save(std::string const& filename, std::vector<int> const& keyframes, vfr::Framerate const& fps) {
|
||||
io::Save file(filename);
|
||||
std::ofstream& of = file.Get();
|
||||
of << "# keyframe format v1" << std::endl;
|
||||
of << "fps " << fps.FPS() << std::endl;
|
||||
std::copy(keyframes.begin(), keyframes.end(), std::ostream_iterator<int>(of, "\n"));
|
||||
}
|
||||
|
||||
std::pair<std::vector<int>, double> Load(std::string const& filename) {
|
||||
std::auto_ptr<std::ifstream> file(io::Open(filename));
|
||||
std::istream &is(*file.get());
|
||||
|
||||
std::string header;
|
||||
std::getline(is, header);
|
||||
|
||||
if (header == "# keyframe format v1") return agi_keyframes(is);
|
||||
if (starts_with(header, "# XviD 2pass stat file")) return other_keyframes(is, xvid);
|
||||
if (starts_with(header, "##map version")) return other_keyframes(is, divx);
|
||||
if (starts_with(header, "#options:")) return other_keyframes(is, x264);
|
||||
|
||||
throw Error("Unknown keyframe format");
|
||||
}
|
||||
|
||||
} }
|
43
aegisub/libaegisub/include/libaegisub/keyframe.h
Normal file
43
aegisub/libaegisub/include/libaegisub/keyframe.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
// Copyright (c) 2011, Thomas Goyne <plorkyeran@aegisub.org>
|
||||
//
|
||||
// Permission to use, copy, modify, and distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
/// @file keyframe.h
|
||||
/// @see keyframe.cpp
|
||||
/// @ingroup libaegisub
|
||||
///
|
||||
|
||||
#if !defined(AGI_PRE) && !defined(LAGI_PRE)
|
||||
#include <vector>
|
||||
#endif
|
||||
|
||||
#include "exception.h"
|
||||
|
||||
namespace agi {
|
||||
namespace vfr { class Framerate; }
|
||||
namespace keyframe {
|
||||
/// @brief Load a keyframe file
|
||||
/// @param filename File to load
|
||||
/// @return Pair of frame numbers which are keyframes and fps
|
||||
std::pair<std::vector<int>, double> Load(std::string const& filename);
|
||||
/// @brief Save keyframes to a file
|
||||
/// @param filename File to save to
|
||||
/// @param keyframes List of keyframes to save
|
||||
/// @param fps Current fps that goes with the keyframes
|
||||
void Save(std::string const& filename, std::vector<int> const& keyframes, vfr::Framerate const& fps);
|
||||
|
||||
DEFINE_SIMPLE_EXCEPTION_NOINNER(Error, Exception, "keyframe/error")
|
||||
}
|
||||
}
|
|
@ -194,7 +194,6 @@ SRC += \
|
|||
help_button.cpp \
|
||||
hotkeys.cpp \
|
||||
kana_table.cpp \
|
||||
keyframe.cpp \
|
||||
main.cpp \
|
||||
md5.c \
|
||||
mkv_wrap.cpp \
|
||||
|
|
|
@ -64,7 +64,6 @@
|
|||
#include "frame_main.h"
|
||||
#include "help_button.h"
|
||||
#include "hotkeys.h"
|
||||
#include "keyframe.h"
|
||||
#include "libresrc/libresrc.h"
|
||||
#include "main.h"
|
||||
#include "standard_paths.h"
|
||||
|
|
|
@ -81,7 +81,7 @@
|
|||
#include "frame_main.h"
|
||||
#include "hotkeys.h"
|
||||
#include "include/aegisub/audio_player.h"
|
||||
#include "keyframe.h"
|
||||
#include "libaegisub/charset_conv.h"
|
||||
#include "libresrc/libresrc.h"
|
||||
#include "main.h"
|
||||
#include "preferences.h"
|
||||
|
|
|
@ -1,177 +0,0 @@
|
|||
// 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 Project http://www.aegisub.org/
|
||||
//
|
||||
// $Id$
|
||||
|
||||
/// @file keyframe.cpp
|
||||
/// @brief Read and store video keyframe data
|
||||
/// @ingroup video_input
|
||||
///
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef AGI_PRE
|
||||
#include <wx/msgdlg.h>
|
||||
#endif
|
||||
|
||||
#include "compat.h"
|
||||
#include "keyframe.h"
|
||||
#include "main.h"
|
||||
#include "text_file_reader.h"
|
||||
#include "text_file_writer.h"
|
||||
#include "video_context.h"
|
||||
|
||||
std::vector<int> KeyFrameFile::Load(wxString filename) {
|
||||
std::vector<int> keyFrames;
|
||||
TextFileReader file(filename,_T("ASCII"));
|
||||
|
||||
wxString cur = file.ReadLineFromFile();
|
||||
// Detect type (Only Xvid, DivX, x264 and Aegisub's keyframe files are currently supported)
|
||||
if (cur == _T("# keyframe format v1")) { OpenAegiKeyFrames(file, keyFrames); }
|
||||
else if (cur.StartsWith(_T("# XviD 2pass stat file"))) { OpenXviDKeyFrames(file, keyFrames); }
|
||||
else if (cur.StartsWith(_T("##map version"))) { OpenDivXKeyFrames(file, keyFrames); }
|
||||
else if (cur.StartsWith(_T("#options:"))) { Openx264KeyFrames(file, keyFrames); }
|
||||
else { throw(_T("Invalid or unsupported keyframes file.")); }
|
||||
|
||||
config::mru->Add("Keyframes", STD_STR(filename));
|
||||
return keyFrames;
|
||||
}
|
||||
|
||||
void KeyFrameFile::Save(wxString filename, std::vector<int> const& keyFrames) {
|
||||
TextFileWriter file(filename,_T("ASCII"));
|
||||
file.WriteLineToFile(_T("# keyframe format v1"));
|
||||
file.WriteLineToFile(wxString::Format(_T("fps %f"),VideoContext::Get()->VFR_Input.FPS()));
|
||||
|
||||
for (unsigned int i=0;i<keyFrames.size();i++) {
|
||||
file.WriteLineToFile(wxString::Format(_T("%i"),keyFrames[i]));
|
||||
}
|
||||
|
||||
config::mru->Add("Keyframes", STD_STR(filename));
|
||||
}
|
||||
|
||||
/// @brief Aegisub keyframes file
|
||||
/// @param file
|
||||
/// @param keyFrames
|
||||
///
|
||||
void KeyFrameFile::OpenAegiKeyFrames(TextFileReader& file, std::vector<int>& 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()->TimecodesLoaded()) {
|
||||
VideoContext::Get()->ovrFPS = fps;
|
||||
}
|
||||
|
||||
// Read lines
|
||||
while (file.HasMoreLines()) {
|
||||
cur = file.ReadLineFromFile();
|
||||
if (!cur.IsEmpty() && !cur.StartsWith(_T("#")) && cur.IsNumber()) {
|
||||
long temp;
|
||||
cur.ToLong(&temp);
|
||||
keyFrames.push_back(temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief XviD stats file
|
||||
/// @param file
|
||||
/// @param keyFrames
|
||||
///
|
||||
void KeyFrameFile::OpenXviDKeyFrames(TextFileReader& file, std::vector<int>& keyFrames)
|
||||
{
|
||||
wxString cur = file.ReadLineFromFile();
|
||||
unsigned int count = 0;
|
||||
|
||||
// Read lines
|
||||
while (file.HasMoreLines()) {
|
||||
if (cur.StartsWith(_T("i"))) {
|
||||
keyFrames.push_back(count);
|
||||
count++;
|
||||
}
|
||||
else if (cur.StartsWith(_T("p")) || cur.StartsWith(_T("b"))) {
|
||||
count++;
|
||||
}
|
||||
cur = file.ReadLineFromFile();
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief DivX stats file
|
||||
/// @param file
|
||||
/// @param keyFrames
|
||||
///
|
||||
void KeyFrameFile::OpenDivXKeyFrames(TextFileReader& file, std::vector<int>& keyFrames)
|
||||
{
|
||||
wxString cur = file.ReadLineFromFile();
|
||||
unsigned int count = 0;
|
||||
|
||||
// Read lines
|
||||
while (file.HasMoreLines())
|
||||
{
|
||||
if (cur.Contains(_T("I"))) {
|
||||
keyFrames.push_back(count);
|
||||
count++;
|
||||
}
|
||||
else if (cur.Contains(_T("P")) || cur.Contains(_T("B"))) {
|
||||
count++;
|
||||
}
|
||||
cur = file.ReadLineFromFile();
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief x264 stats file
|
||||
/// @param file
|
||||
/// @param keyFrames
|
||||
///
|
||||
void KeyFrameFile::Openx264KeyFrames(TextFileReader& file, std::vector<int>& keyFrames)
|
||||
{
|
||||
wxString cur = file.ReadLineFromFile();
|
||||
unsigned int count = 0;
|
||||
size_t pos;
|
||||
|
||||
// Read lines
|
||||
while (file.HasMoreLines())
|
||||
{
|
||||
pos = cur.Find(_T("type:"));
|
||||
if (cur.Mid(pos,6).Right(1).Lower() == (_T("i"))) {
|
||||
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"))) {
|
||||
count++;
|
||||
}
|
||||
cur = file.ReadLineFromFile();
|
||||
}
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
// 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 Project http://www.aegisub.org/
|
||||
//
|
||||
// $Id$
|
||||
|
||||
/// @file keyframe.h
|
||||
/// @see keyframe.cpp
|
||||
/// @ingroup video_input
|
||||
///
|
||||
|
||||
#include "text_file_reader.h"
|
||||
|
||||
|
||||
/// DOCME
|
||||
/// @class KeyFrameFile
|
||||
/// @brief DOCME
|
||||
///
|
||||
/// DOCME
|
||||
class KeyFrameFile
|
||||
{
|
||||
public:
|
||||
static std::vector<int> Load(wxString filename);
|
||||
static void Save(wxString filename, std::vector<int> const& keyframes);
|
||||
private:
|
||||
static void OpenAegiKeyFrames(TextFileReader& file, std::vector<int>& keyFrames);
|
||||
static void OpenXviDKeyFrames(TextFileReader& file, std::vector<int>& keyFrames);
|
||||
static void OpenDivXKeyFrames(TextFileReader& file, std::vector<int>& keyFrames);
|
||||
static void Openx264KeyFrames(TextFileReader& file, std::vector<int>& keyFrames);
|
||||
};
|
||||
|
||||
|
|
@ -64,7 +64,7 @@
|
|||
#include "include/aegisub/audio_player.h"
|
||||
#include "include/aegisub/audio_provider.h"
|
||||
#include "include/aegisub/video_provider.h"
|
||||
#include "keyframe.h"
|
||||
#include <libaegisub/keyframe.h>
|
||||
#include <libaegisub/access.h>
|
||||
#include "main.h"
|
||||
#include "mkv_wrap.h"
|
||||
|
@ -454,24 +454,30 @@ void VideoContext::SetAspectRatio(int type, double value) {
|
|||
void VideoContext::LoadKeyframes(wxString filename) {
|
||||
if (filename == keyFramesFilename || filename.empty()) return;
|
||||
try {
|
||||
keyFrames = KeyFrameFile::Load(filename);
|
||||
std::pair<std::vector<int>, double> kf = agi::keyframe::Load(STD_STR(filename));
|
||||
keyFrames = kf.first;
|
||||
keyFramesFilename = filename;
|
||||
KeyframesOpen(keyFrames);
|
||||
if (kf.second != 0.) {
|
||||
ovrFPS = agi::vfr::Framerate(kf.second);
|
||||
ovrTimecodeFile.clear();
|
||||
SubtitlesChanged();
|
||||
}
|
||||
config::mru->Add("Keyframes", STD_STR(filename));
|
||||
}
|
||||
catch (const wchar_t *error) {
|
||||
wxMessageBox(error, _T("Error opening keyframes file"), wxOK | wxICON_ERROR, NULL);
|
||||
}
|
||||
catch (agi::acs::AcsNotFound const&) {
|
||||
wxLogError(L"Could not open file " + filename);
|
||||
catch (agi::keyframe::Error const& err) {
|
||||
wxMessageBox(err.GetMessage(), "Error opening keyframes file", wxOK | wxICON_ERROR, NULL);
|
||||
config::mru->Remove("Keyframes", STD_STR(filename));
|
||||
}
|
||||
catch (...) {
|
||||
wxMessageBox(_T("Unknown error"), _T("Error opening keyframes file"), wxOK | wxICON_ERROR, NULL);
|
||||
catch (agi::acs::AcsError const&) {
|
||||
wxLogError(L"Could not open file " + filename);
|
||||
config::mru->Remove("Keyframes", STD_STR(filename));
|
||||
}
|
||||
}
|
||||
|
||||
void VideoContext::SaveKeyframes(wxString filename) {
|
||||
KeyFrameFile::Save(filename, GetKeyFrames());
|
||||
agi::keyframe::Save(STD_STR(filename), GetKeyFrames(), FPS());
|
||||
config::mru->Add("Keyframes", STD_STR(filename));
|
||||
}
|
||||
|
||||
void VideoContext::CloseKeyframes() {
|
||||
|
|
|
@ -57,7 +57,6 @@ class SubtitlesGrid;
|
|||
class AudioProvider;
|
||||
class AudioDisplay;
|
||||
class AssDialogue;
|
||||
class KeyFrameFile;
|
||||
class SubtitlesProviderErrorEvent;
|
||||
class ThreadedFrameSource;
|
||||
class VideoProvider;
|
||||
|
@ -75,7 +74,6 @@ namespace agi {
|
|||
/// DOCME
|
||||
class VideoContext : public wxEvtHandler {
|
||||
friend class AudioProvider;
|
||||
friend class KeyFrameFile;
|
||||
|
||||
/// Current frame number changed (new frame number)
|
||||
agi::signal::Signal<int> Seek;
|
||||
|
|
Loading…
Reference in a new issue