Add support for WWXD keyframes in qpfile format
This commit is contained in:
parent
747525142a
commit
a621072e7d
3 changed files with 41 additions and 10 deletions
|
@ -19,6 +19,8 @@
|
|||
|
||||
#include "libaegisub/keyframe.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "libaegisub/io.h"
|
||||
#include "libaegisub/line_iterator.h"
|
||||
|
||||
|
@ -35,10 +37,9 @@ std::vector<int> agi_keyframes(std::istream &file) {
|
|||
return std::vector<int>(agi::line_iterator<int>(file), agi::line_iterator<int>());
|
||||
}
|
||||
|
||||
std::vector<int> other_keyframes(std::istream &file, char (*func)(std::string const&)) {
|
||||
std::vector<int> enumerated_keyframes(std::istream &file, char (*func)(std::string const&)) {
|
||||
int count = 0;
|
||||
std::vector<int> ret;
|
||||
agi::line_iterator<std::string> end;
|
||||
for (auto line : agi::line_iterator<std::string>(file)) {
|
||||
char c = tolower(func(line));
|
||||
if (c == 'i')
|
||||
|
@ -49,6 +50,16 @@ std::vector<int> other_keyframes(std::istream &file, char (*func)(std::string co
|
|||
return ret;
|
||||
}
|
||||
|
||||
std::vector<int> indexed_keyframes(std::istream &file, int (*func)(std::string const&)) {
|
||||
std::vector<int> ret;
|
||||
for (auto line : agi::line_iterator<std::string>(file)) {
|
||||
int frame_no = func(line);
|
||||
if (frame_no >= 0)
|
||||
ret.push_back(frame_no);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
char xvid(std::string const& line) {
|
||||
return line.empty() ? 0 : line[0];
|
||||
}
|
||||
|
@ -68,6 +79,20 @@ char x264(std::string const& line) {
|
|||
if (pos == line.npos || pos + 5 >= line.size()) return 0;
|
||||
return line[pos + 5];
|
||||
}
|
||||
|
||||
int wwxd(std::string const& line) {
|
||||
if (line.empty() || line[0] == '#')
|
||||
return -1;
|
||||
std::istringstream ss(line);
|
||||
int frame_no;
|
||||
char frame_type;
|
||||
ss >> frame_no >> frame_type;
|
||||
if (ss.fail())
|
||||
throw agi::keyframe::KeyframeFormatParseError("WWXD keyframe file not in qpfile format");
|
||||
if (frame_type == 'I')
|
||||
return frame_no;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
namespace agi { namespace keyframe {
|
||||
|
@ -87,13 +112,14 @@ std::vector<int> Load(agi::fs::path const& filename) {
|
|||
getline(is, header);
|
||||
|
||||
if (header == "# keyframe format v1") return agi_keyframes(is);
|
||||
if (boost::starts_with(header, "# XviD 2pass stat file")) return other_keyframes(is, xvid);
|
||||
if (boost::starts_with(header, "# ffmpeg 2-pass log file, using xvid codec")) return other_keyframes(is, xvid);
|
||||
if (boost::starts_with(header, "# avconv 2-pass log file, using xvid codec")) return other_keyframes(is, xvid);
|
||||
if (boost::starts_with(header, "##map version")) return other_keyframes(is, divx);
|
||||
if (boost::starts_with(header, "#options:")) return other_keyframes(is, x264);
|
||||
if (boost::starts_with(header, "# XviD 2pass stat file")) return enumerated_keyframes(is, xvid);
|
||||
if (boost::starts_with(header, "# ffmpeg 2-pass log file, using xvid codec")) return enumerated_keyframes(is, xvid);
|
||||
if (boost::starts_with(header, "# avconv 2-pass log file, using xvid codec")) return enumerated_keyframes(is, xvid);
|
||||
if (boost::starts_with(header, "##map version")) return enumerated_keyframes(is, divx);
|
||||
if (boost::starts_with(header, "#options:")) return enumerated_keyframes(is, x264);
|
||||
if (boost::starts_with(header, "# WWXD log file, using qpfile format")) return indexed_keyframes(is, wwxd);
|
||||
|
||||
throw Error("Unknown keyframe format");
|
||||
throw UnknownKeyframeFormatError("File header does not match any known formats");
|
||||
}
|
||||
|
||||
} }
|
||||
|
|
|
@ -29,6 +29,7 @@ namespace agi {
|
|||
/// @param keyframes List of keyframes to save
|
||||
void Save(agi::fs::path const& filename, std::vector<int> const& keyframes);
|
||||
|
||||
DEFINE_EXCEPTION(Error, Exception);
|
||||
DEFINE_EXCEPTION(KeyframeFormatParseError, agi::InvalidInputException);
|
||||
DEFINE_EXCEPTION(UnknownKeyframeFormatError, agi::InvalidInputException);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -391,10 +391,14 @@ void Project::LoadKeyframes(agi::fs::path path) {
|
|||
ShowError(e.GetMessage());
|
||||
config::mru->Remove("Keyframes", path);
|
||||
}
|
||||
catch (agi::keyframe::Error const& e) {
|
||||
catch (agi::keyframe::KeyframeFormatParseError const& e) {
|
||||
ShowError("Failed to parse keyframes file: " + e.GetMessage());
|
||||
config::mru->Remove("Keyframes", path);
|
||||
}
|
||||
catch (agi::keyframe::UnknownKeyframeFormatError const& e) {
|
||||
ShowError("Keyframes file in unknown format: " + e.GetMessage());
|
||||
config::mru->Remove("Keyframes", path);
|
||||
}
|
||||
}
|
||||
|
||||
void Project::CloseKeyframes() {
|
||||
|
|
Loading…
Reference in a new issue