forked from mia/Aegisub
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
|
<Filter
|
||||||
Name="Video backend"
|
Name="Video backend"
|
||||||
>
|
>
|
||||||
<File
|
|
||||||
RelativePath="..\..\src\keyframe.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="..\..\src\keyframe.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\src\threaded_frame_source.cpp"
|
RelativePath="..\..\src\threaded_frame_source.cpp"
|
||||||
>
|
>
|
||||||
|
|
|
@ -275,6 +275,10 @@
|
||||||
RelativePath="..\..\libaegisub\common\charset_ucd.cpp"
|
RelativePath="..\..\libaegisub\common\charset_ucd.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\libaegisub\common\keyframe.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\libaegisub\common\log.cpp"
|
RelativePath="..\..\libaegisub\common\log.cpp"
|
||||||
>
|
>
|
||||||
|
@ -421,6 +425,10 @@
|
||||||
RelativePath="..\..\libaegisub\include\libaegisub\io.h"
|
RelativePath="..\..\libaegisub\include\libaegisub\io.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\libaegisub\include\libaegisub\keyframe.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\libaegisub\include\libaegisub\line_iterator.h"
|
RelativePath="..\..\libaegisub\include\libaegisub\line_iterator.h"
|
||||||
>
|
>
|
||||||
|
|
|
@ -24,6 +24,7 @@ SRC = \
|
||||||
common/mru.cpp \
|
common/mru.cpp \
|
||||||
common/option.cpp \
|
common/option.cpp \
|
||||||
common/option_visit.cpp \
|
common/option_visit.cpp \
|
||||||
|
common/keyframe.cpp \
|
||||||
common/log.cpp \
|
common/log.cpp \
|
||||||
common/validator.cpp \
|
common/validator.cpp \
|
||||||
common/vfr.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 \
|
help_button.cpp \
|
||||||
hotkeys.cpp \
|
hotkeys.cpp \
|
||||||
kana_table.cpp \
|
kana_table.cpp \
|
||||||
keyframe.cpp \
|
|
||||||
main.cpp \
|
main.cpp \
|
||||||
md5.c \
|
md5.c \
|
||||||
mkv_wrap.cpp \
|
mkv_wrap.cpp \
|
||||||
|
|
|
@ -64,7 +64,6 @@
|
||||||
#include "frame_main.h"
|
#include "frame_main.h"
|
||||||
#include "help_button.h"
|
#include "help_button.h"
|
||||||
#include "hotkeys.h"
|
#include "hotkeys.h"
|
||||||
#include "keyframe.h"
|
|
||||||
#include "libresrc/libresrc.h"
|
#include "libresrc/libresrc.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "standard_paths.h"
|
#include "standard_paths.h"
|
||||||
|
|
|
@ -81,7 +81,7 @@
|
||||||
#include "frame_main.h"
|
#include "frame_main.h"
|
||||||
#include "hotkeys.h"
|
#include "hotkeys.h"
|
||||||
#include "include/aegisub/audio_player.h"
|
#include "include/aegisub/audio_player.h"
|
||||||
#include "keyframe.h"
|
#include "libaegisub/charset_conv.h"
|
||||||
#include "libresrc/libresrc.h"
|
#include "libresrc/libresrc.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "preferences.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_player.h"
|
||||||
#include "include/aegisub/audio_provider.h"
|
#include "include/aegisub/audio_provider.h"
|
||||||
#include "include/aegisub/video_provider.h"
|
#include "include/aegisub/video_provider.h"
|
||||||
#include "keyframe.h"
|
#include <libaegisub/keyframe.h>
|
||||||
#include <libaegisub/access.h>
|
#include <libaegisub/access.h>
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "mkv_wrap.h"
|
#include "mkv_wrap.h"
|
||||||
|
@ -454,24 +454,30 @@ void VideoContext::SetAspectRatio(int type, double value) {
|
||||||
void VideoContext::LoadKeyframes(wxString filename) {
|
void VideoContext::LoadKeyframes(wxString filename) {
|
||||||
if (filename == keyFramesFilename || filename.empty()) return;
|
if (filename == keyFramesFilename || filename.empty()) return;
|
||||||
try {
|
try {
|
||||||
keyFrames = KeyFrameFile::Load(filename);
|
std::pair<std::vector<int>, double> kf = agi::keyframe::Load(STD_STR(filename));
|
||||||
|
keyFrames = kf.first;
|
||||||
keyFramesFilename = filename;
|
keyFramesFilename = filename;
|
||||||
KeyframesOpen(keyFrames);
|
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) {
|
catch (agi::keyframe::Error const& err) {
|
||||||
wxMessageBox(error, _T("Error opening keyframes file"), wxOK | wxICON_ERROR, NULL);
|
wxMessageBox(err.GetMessage(), "Error opening keyframes file", wxOK | wxICON_ERROR, NULL);
|
||||||
}
|
|
||||||
catch (agi::acs::AcsNotFound const&) {
|
|
||||||
wxLogError(L"Could not open file " + filename);
|
|
||||||
config::mru->Remove("Keyframes", STD_STR(filename));
|
config::mru->Remove("Keyframes", STD_STR(filename));
|
||||||
}
|
}
|
||||||
catch (...) {
|
catch (agi::acs::AcsError const&) {
|
||||||
wxMessageBox(_T("Unknown error"), _T("Error opening keyframes file"), wxOK | wxICON_ERROR, NULL);
|
wxLogError(L"Could not open file " + filename);
|
||||||
|
config::mru->Remove("Keyframes", STD_STR(filename));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoContext::SaveKeyframes(wxString 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() {
|
void VideoContext::CloseKeyframes() {
|
||||||
|
|
|
@ -57,7 +57,6 @@ class SubtitlesGrid;
|
||||||
class AudioProvider;
|
class AudioProvider;
|
||||||
class AudioDisplay;
|
class AudioDisplay;
|
||||||
class AssDialogue;
|
class AssDialogue;
|
||||||
class KeyFrameFile;
|
|
||||||
class SubtitlesProviderErrorEvent;
|
class SubtitlesProviderErrorEvent;
|
||||||
class ThreadedFrameSource;
|
class ThreadedFrameSource;
|
||||||
class VideoProvider;
|
class VideoProvider;
|
||||||
|
@ -75,7 +74,6 @@ namespace agi {
|
||||||
/// DOCME
|
/// DOCME
|
||||||
class VideoContext : public wxEvtHandler {
|
class VideoContext : public wxEvtHandler {
|
||||||
friend class AudioProvider;
|
friend class AudioProvider;
|
||||||
friend class KeyFrameFile;
|
|
||||||
|
|
||||||
/// Current frame number changed (new frame number)
|
/// Current frame number changed (new frame number)
|
||||||
agi::signal::Signal<int> Seek;
|
agi::signal::Signal<int> Seek;
|
||||||
|
|
Loading…
Reference in a new issue