Conversion task working for both directions

This commit is contained in:
Gene Payne
2020-07-14 17:19:24 -06:00
parent 1c108f99d3
commit cd7be9b870
8 changed files with 211 additions and 119 deletions

View File

@@ -0,0 +1,7 @@
return {
{
Type = "ConvertRecFormatTask",
InputFilePath = "../../recordings/input",
OutputFilePath = "../../recordings/output"
}
}

View File

@@ -32,13 +32,21 @@
namespace openspace::interaction {
enum class SessionRecordingDataMode {
Ascii = 0,
Binary,
Unknown
};
static const std::string SessionRecordingFileHeaderTitle = "OpenSpace_record/playback";
static const std::string SessionRecordingHeaderCameraAscii = "camera";
static const std::string SessionRecordingHeaderTimeAscii = "time";
static const std::string SessionRecordingHeaderScriptAscii = "script";
static const char SessionRecordingHeaderCameraBinary = 'c';
static const char SessionRecordingHeaderTimeBinary = 't';
static const char SessionRecordingHeaderScriptBinary = 's';
class SessionRecording : public properties::PropertyOwner {
public:
enum class RecordedDataMode {
Ascii = 0,
Binary
};
enum class SessionState {
Idle = 0,
Recording,
@@ -51,14 +59,12 @@ public:
double timeSim;
};
const std::string FileHeaderTitle = "OpenSpace_record/playback";
static const size_t FileHeaderVersionLength = 5;
const char FileHeaderVersion[FileHeaderVersionLength] = {
static constexpr char FileHeaderVersion[FileHeaderVersionLength] = {
'0', '0', '.', '8', '5'
};
const char DataFormatAsciiTag = 'A';
const char DataFormatBinaryTag = 'B';
static const char DataFormatAsciiTag = 'A';
static const char DataFormatBinaryTag = 'B';
static const size_t keyframeHeaderSize_bytes = 33;
static const size_t saveBufferCameraSize_min = 82;
static const size_t saveBufferStringSize_max = 500;
@@ -114,7 +120,7 @@ public:
*
* \return \c true if recording to file starts without errors
*/
void setRecordDataFormat(RecordedDataMode dataMode);
void setRecordDataFormat(SessionRecordingDataMode dataMode);
/**
* Used to stop a recording in progress. If open, the recording file will be closed,
@@ -246,11 +252,12 @@ public:
*
* \param times reference to a timestamps structure which contains recorded times
* \param kf reference to a camera keyframe which contains camera details
* \param filenameRead a string containing the playback filename
* \param currentParsingLine string containing the most current line that was read
* \param lineN line number in playback file where this keyframe resides
*/
static void readCameraKeyframeAscii(timestamps& times,
datamessagestructures::CameraKeyframe& kf, std::string filenameRead, int lineN);
datamessagestructures::CameraKeyframe& kf, std::string currentParsingLine,
int lineN);
/**
* Reads a time keyframe from a binary format playback file, and populates input
@@ -270,11 +277,12 @@ public:
*
* \param times reference to a timestamps structure which contains recorded times
* \param kf reference to a time keyframe which contains time details
* \param filenameRead a string containing the playback filename
* \param currentParsingLine string containing the most current line that was read
* \param lineN line number in playback file where this keyframe resides
*/
static void readTimeKeyframeAscii(timestamps& times,
datamessagestructures::TimeKeyframe& kf, std::string filenameRead, int lineN);
datamessagestructures::TimeKeyframe& kf, std::string currentParsingLine,
int lineN);
/**
* Reads a script keyframe from a binary format playback file, and populates input
@@ -296,11 +304,12 @@ public:
* \param times reference to a timestamps structure which contains recorded times
* \param kf reference to a script keyframe which contains the size of the script
* (in chars) and the text itself
* \param filenameRead a string containing the playback filename
* \param currentParsingLine string containing the most current line that was read
* \param lineN line number in playback file where this keyframe resides
*/
static void readScriptKeyframeAscii(timestamps& times,
datamessagestructures::ScriptMessage& kf, std::string filenameRead, int lineN);
datamessagestructures::ScriptMessage& kf, std::string currentParsingLine,
int lineN);
/**
* Writes a camera keyframe to a binary format recording file using a CameraKeyframe
@@ -377,6 +386,35 @@ public:
*/
static std::string readHeaderElement(std::ifstream& stream, size_t readLen_chars);
/**
* Writes a header to a binary recording file buffer
*
* \param times reference to a timestamps structure which contains recorded times
* \param type single character signifying the keyframe type
* \param kfBuffer the char buffer holding the recording info to be written
* \param idx index into write buffer (this is updated with the num of chars written)
*/
static void saveHeaderBinary(timestamps times, char type, unsigned char* kfBuffer,
size_t& idx);
/**
* Writes a header to an ascii recording file buffer
*
* \param times reference to a timestamps structure which contains recorded times
* \param type string signifying the keyframe type
* \param line the stringstream buffer being written to
*/
static void saveHeaderAscii(timestamps times, const std::string& type,
std::stringstream& line);
/**
* Saves a keyframe to an ascii recording file
*
* \param entry the ascii string version of the keyframe (any type)
* \param file ofstream object to write to
*/
static void saveKeyframeToFile(std::string entry, std::ofstream& file);
private:
enum class RecordedType {
Camera = 0,
@@ -409,7 +447,6 @@ private:
std::ofstream& file);
static void saveKeyframeToFileBinary(unsigned char* bufferSource, size_t size,
std::ofstream& file);
static void saveKeyframeToFile(std::string entry, std::ofstream& file);
void addKeyframe(double timestamp,
interaction::KeyframeNavigator::CameraPose keyframe);
@@ -439,12 +476,7 @@ private:
static void writeToFileBuffer(unsigned char* buf, size_t& idx, unsigned char c);
static void writeToFileBuffer(unsigned char* buf, size_t& idx, bool b);
static void saveHeaderBinary(timestamps times, char type,
unsigned char* kfBuffer, size_t& idx);
static void saveHeaderAscii(timestamps times, const std::string& type,
std::stringstream& line);
RecordedDataMode _recordingDataMode = RecordedDataMode::Binary;
SessionRecordingDataMode _recordingDataMode = SessionRecordingDataMode::Binary;
SessionState _state = SessionState::Idle;
SessionState _lastState = SessionState::Idle;
std::string _playbackFilename;

View File

@@ -53,20 +53,19 @@ public:
void perform(const Task::ProgressCallback& progressCallback) override;
static documentation::Documentation documentation();
void convert();
SessionRecording::RecordedDataMode ConvertRecFormatTask::formatType();
private:
void convertToAscii();
void convertToBinary();
void determineFormatType();
std::string addFileSuffix(const std::string& filePath, const std::string& suffix);
std::string _inFilePath;
std::string _outFilePath;
std::ifstream _iFile;
std::ofstream _oFile;
SessionRecordingDataMode _fileFormatType;
std::string _valueFunctionLua;
SessionRecording sr;
};
} // namespace openspace::interaction

View File

@@ -429,6 +429,12 @@ struct ScriptMessage {
double _timestamp;
void serialize(std::vector<char> &buffer) const {
size_t strLen = _script.size();
size_t writeSize_bytes = sizeof(size_t);
unsigned char const *p = reinterpret_cast<unsigned char const*>(&strLen);
buffer.insert(buffer.end(), p, p + writeSize_bytes);
buffer.insert(buffer.end(), _script.begin(), _script.end());
};
@@ -486,6 +492,8 @@ struct ScriptMessage {
_script.erase();
for (int i = 0; i < numScriptLines; ++i) {
std::getline(iss, tmpReadbackScript);
size_t start = tmpReadbackScript.find_first_not_of(" ");
tmpReadbackScript = tmpReadbackScript.substr(start);
_script.append(tmpReadbackScript);
if (i < (numScriptLines - 1)) {
_script.append("\n");

View File

@@ -63,6 +63,7 @@ set(OPENSPACE_SOURCE
${OPENSPACE_BASE_DIR}/src/interaction/shortcutmanager_lua.inl
${OPENSPACE_BASE_DIR}/src/interaction/websocketinputstate.cpp
${OPENSPACE_BASE_DIR}/src/interaction/websocketcamerastates.cpp
${OPENSPACE_BASE_DIR}/src/interaction/tasks/convertrecformattask.cpp
${OPENSPACE_BASE_DIR}/src/mission/mission.cpp
${OPENSPACE_BASE_DIR}/src/mission/missionmanager.cpp
${OPENSPACE_BASE_DIR}/src/mission/missionmanager_lua.inl
@@ -245,6 +246,7 @@ set(OPENSPACE_HEADER
${OPENSPACE_BASE_DIR}/include/openspace/interaction/shortcutmanager.h
${OPENSPACE_BASE_DIR}/include/openspace/interaction/websocketinputstate.h
${OPENSPACE_BASE_DIR}/include/openspace/interaction/websocketcamerastates.h
${OPENSPACE_BASE_DIR}/include/openspace/interaction/tasks/convertrecformattask.h
${OPENSPACE_BASE_DIR}/include/openspace/mission/mission.h
${OPENSPACE_BASE_DIR}/include/openspace/mission/missionmanager.h
${OPENSPACE_BASE_DIR}/include/openspace/network/parallelconnection.h

View File

@@ -29,6 +29,7 @@
#include <openspace/interaction/keyframenavigator.h>
#include <openspace/interaction/navigationhandler.h>
#include <openspace/interaction/orbitalnavigator.h>
#include <openspace/interaction/tasks/convertrecformattask.h>
#include <openspace/rendering/luaconsole.h>
#include <openspace/rendering/renderable.h>
#include <openspace/rendering/renderengine.h>
@@ -36,6 +37,8 @@
#include <openspace/scripting/scriptengine.h>
#include <openspace/scripting/scriptscheduler.h>
#include <openspace/util/camera.h>
#include <openspace/util/factorymanager.h>
#include <openspace/util/task.h>
#include <openspace/util/timemanager.h>
#include <ghoul/filesystem/file.h>
#include <ghoul/filesystem/filesystem.h>
@@ -57,7 +60,11 @@ namespace openspace::interaction {
SessionRecording::SessionRecording()
: properties::PropertyOwner({ "SessionRecording", "Session Recording" })
{}
{
auto fTask = FactoryManager::ref().factory<Task>();
ghoul_assert(fRenderable, "No task factory existed");
fTask->registerClass<ConvertRecFormatTask>("ConvertRecFormatTask");
}
SessionRecording::~SessionRecording() {} // NOLINT
@@ -66,7 +73,7 @@ void SessionRecording::deinitialize() {
stopPlayback();
}
void SessionRecording::setRecordDataFormat(RecordedDataMode dataMode) {
void SessionRecording::setRecordDataFormat(SessionRecordingDataMode dataMode) {
_recordingDataMode = dataMode;
}
@@ -102,7 +109,7 @@ bool SessionRecording::startRecording(const std::string& filename) {
_playbackActive_camera = false;
_playbackActive_time = false;
_playbackActive_script = false;
if (_recordingDataMode == RecordedDataMode::Binary) {
if (_recordingDataMode == SessionRecordingDataMode::Binary) {
_recordFile.open(absFilename, std::ios::binary);
}
else {
@@ -115,9 +122,9 @@ bool SessionRecording::startRecording(const std::string& filename) {
));
return false;
}
_recordFile << FileHeaderTitle;
_recordFile << SessionRecordingFileHeaderTitle;
_recordFile.write(FileHeaderVersion, FileHeaderVersionLength);
if (_recordingDataMode == RecordedDataMode::Binary) {
if (_recordingDataMode == SessionRecordingDataMode::Binary) {
_recordFile << DataFormatBinaryTag;
}
else {
@@ -180,9 +187,9 @@ bool SessionRecording::startPlayback(const std::string& filename,
// Read header
std::string readBackHeaderString = readHeaderElement(
_playbackFile,
FileHeaderTitle.length()
SessionRecordingFileHeaderTitle.length()
);
if (readBackHeaderString != FileHeaderTitle) {
if (readBackHeaderString != SessionRecordingFileHeaderTitle) {
LERROR("Specified playback file does not contain expected header.");
cleanUpPlayback();
return false;
@@ -190,10 +197,10 @@ bool SessionRecording::startPlayback(const std::string& filename,
readHeaderElement(_playbackFile, FileHeaderVersionLength);
std::string readDataMode = readHeaderElement(_playbackFile, 1);
if (readDataMode[0] == DataFormatAsciiTag) {
_recordingDataMode = RecordedDataMode::Ascii;
_recordingDataMode = SessionRecordingDataMode::Ascii;
}
else if (readDataMode[0] == DataFormatBinaryTag) {
_recordingDataMode = RecordedDataMode::Binary;
_recordingDataMode = SessionRecordingDataMode::Binary;
}
else {
LERROR("Unknown data type in header (should be Ascii or Binary)");
@@ -201,13 +208,14 @@ bool SessionRecording::startPlayback(const std::string& filename,
}
std::string throwawayNewlineChar = readHeaderElement(_playbackFile, 1);
if (_recordingDataMode == RecordedDataMode::Binary) {
if (_recordingDataMode == SessionRecordingDataMode::Binary) {
//Close & re-open the file, starting from the beginning, and do dummy read
// past the header, version, and data type
_playbackFile.close();
_playbackFile.open(_playbackFilename, std::ifstream::in | std::ios::binary);
size_t headerSize = FileHeaderTitle.length() + FileHeaderVersionLength +
sizeof(DataFormatBinaryTag) + sizeof('\n');
size_t headerSize = SessionRecordingFileHeaderTitle.length() +
FileHeaderVersionLength +
sizeof(DataFormatBinaryTag) + sizeof('\n');
_playbackFile.read(reinterpret_cast<char*>(&_keyframeBuffer), headerSize);
}
@@ -443,7 +451,7 @@ void SessionRecording::saveCameraKeyframe() {
kf._timestamp - _timestampRecordStarted,
global::timeManager.time().j2000Seconds()
};
if (_recordingDataMode == RecordedDataMode::Binary) {
if (_recordingDataMode == SessionRecordingDataMode::Binary) {
saveCameraKeyframeBinary(times, kf, _keyframeBuffer, _recordFile);
}
else {
@@ -479,7 +487,7 @@ void SessionRecording::saveCameraKeyframeBinary(timestamps times,
{
// Writing to a binary session recording file
size_t idx = 0;
saveHeaderBinary(times, 'c', kfBuffer, idx);
saveHeaderBinary(times, SessionRecordingHeaderCameraBinary, kfBuffer, idx);
// Writing to internal buffer, and then to file, for performance reasons
std::vector<char> writeBuffer;
kf.serialize(writeBuffer);
@@ -492,7 +500,7 @@ void SessionRecording::saveCameraKeyframeAscii(timestamps times,
std::ofstream& file)
{
std::stringstream keyframeLine = std::stringstream();
saveHeaderAscii(times, "camera", keyframeLine);
saveHeaderAscii(times, SessionRecordingHeaderCameraAscii, keyframeLine);
kf.write(keyframeLine);
saveKeyframeToFile(keyframeLine.str(), file);
}
@@ -510,7 +518,7 @@ void SessionRecording::saveTimeKeyframe() {
kf._timestamp - _timestampRecordStarted,
global::timeManager.time().j2000Seconds()
};
if (_recordingDataMode == RecordedDataMode::Binary) {
if (_recordingDataMode == SessionRecordingDataMode::Binary) {
saveTimeKeyframeBinary(times, kf, _keyframeBuffer, _recordFile);
} else {
saveTimeKeyframeAscii(times, kf, _recordFile);
@@ -523,7 +531,7 @@ void SessionRecording::saveTimeKeyframeBinary(timestamps times,
std::ofstream& file)
{
size_t idx = 0;
saveHeaderBinary(times, 't', kfBuffer, idx);
saveHeaderBinary(times, SessionRecordingHeaderTimeBinary, kfBuffer, idx);
std::vector<char> writeBuffer;
kf.serialize(writeBuffer);
writeToFileBuffer(kfBuffer, idx, writeBuffer);
@@ -535,7 +543,7 @@ void SessionRecording::saveTimeKeyframeAscii(timestamps times,
std::ofstream& file)
{
std::stringstream keyframeLine = std::stringstream();
saveHeaderAscii(times, "time", keyframeLine);
saveHeaderAscii(times, SessionRecordingHeaderTimeAscii, keyframeLine);
kf.write(keyframeLine);
saveKeyframeToFile(keyframeLine.str(), file);
}
@@ -554,7 +562,7 @@ void SessionRecording::saveScriptKeyframe(std::string scriptToSave) {
global::timeManager.time().j2000Seconds()
};
if (_recordingDataMode == RecordedDataMode::Binary) {
if (_recordingDataMode == SessionRecordingDataMode::Binary) {
saveScriptKeyframeBinary(times, sm, _keyframeBuffer, _recordFile);
}
else {
@@ -568,11 +576,12 @@ void SessionRecording::saveScriptKeyframeBinary(timestamps times,
std::ofstream& file)
{
size_t idx = 0;
saveHeaderBinary(times, 's', smBuffer, idx);
//Write script header to file
saveHeaderBinary(times, SessionRecordingHeaderScriptBinary, smBuffer, idx);
// Writing to internal buffer, and then to file, for performance reasons
std::vector<char> writeBuffer;
sm.serialize(writeBuffer);
writeToFileBuffer(smBuffer, idx, writeBuffer);
saveKeyframeToFileBinary(smBuffer, idx, file);
//Write script data to file
sm.write(smBuffer, idx, file);
}
void SessionRecording::saveScriptKeyframeAscii(timestamps times,
@@ -581,7 +590,7 @@ void SessionRecording::saveScriptKeyframeAscii(timestamps times,
{
std::stringstream keyframeLine = std::stringstream();
saveHeaderAscii(times, "script", keyframeLine);
saveHeaderAscii(times, SessionRecordingHeaderScriptAscii, keyframeLine);
sm.write(keyframeLine);
saveKeyframeToFile(keyframeLine.str(), file);
}
@@ -632,7 +641,7 @@ SessionRecording::SessionState SessionRecording::state() const {
bool SessionRecording::playbackAddEntriesToTimeline() {
bool parsingErrorsFound = false;
if (_recordingDataMode == RecordedDataMode::Binary) {
if (_recordingDataMode == SessionRecordingDataMode::Binary) {
unsigned char frameType;
bool fileReadOk = true;
@@ -647,13 +656,13 @@ bool SessionRecording::playbackAddEntriesToTimeline() {
fileReadOk = false;
break;
}
if (frameType == 'c') {
if (frameType == SessionRecordingHeaderCameraBinary) {
playbackCamera();
}
else if (frameType == 't') {
else if (frameType == SessionRecordingHeaderTimeBinary) {
playbackTimeChange();
}
else if (frameType == 's') {
else if (frameType == SessionRecordingHeaderScriptBinary) {
playbackScript();
}
else {
@@ -682,13 +691,13 @@ bool SessionRecording::playbackAddEntriesToTimeline() {
break;
}
if (entryType == "camera") {
if (entryType == SessionRecordingHeaderCameraAscii) {
playbackCamera();
}
else if (entryType == "time") {
else if (entryType == SessionRecordingHeaderTimeAscii) {
playbackTimeChange();
}
else if (entryType == "script") {
else if (entryType == SessionRecordingHeaderScriptAscii) {
playbackScript();
}
else {
@@ -788,7 +797,7 @@ void SessionRecording::playbackCamera() {
timestamps times;
datamessagestructures::CameraKeyframe kf;
if (_recordingDataMode == RecordedDataMode::Binary) {
if (_recordingDataMode == SessionRecordingDataMode::Binary) {
readCameraKeyframeBinary(times, kf, _playbackFile, _playbackLineNum);
}
else {
@@ -843,16 +852,18 @@ void SessionRecording::readCameraKeyframeBinary(timestamps& times,
void SessionRecording::readCameraKeyframeAscii(timestamps& times,
datamessagestructures::CameraKeyframe& kf,
std::string filenameRead,
std::string currentParsingLine,
int lineN)
{
std::string rotationFollowing;
std::string entryType;
std::istringstream iss(filenameRead);
std::istringstream iss(currentParsingLine);
iss >> entryType;
iss >> times.timeOs >> times.timeRec >> times.timeSim;
kf.read(iss);
//ASCII format does not contain trailing timestamp so add it here
kf._timestamp = times.timeOs;
if (iss.fail() || !iss.eof()) {
LERROR(fmt::format("Error parsing camera line {} of playback file", lineN));
@@ -864,7 +875,7 @@ void SessionRecording::playbackTimeChange() {
timestamps times;
datamessagestructures::TimeKeyframe kf;
if (_recordingDataMode == RecordedDataMode::Binary) {
if (_recordingDataMode == SessionRecordingDataMode::Binary) {
readTimeKeyframeBinary(times, kf, _playbackFile, _playbackLineNum);
} else {
readTimeKeyframeAscii(times, kf, _playbackLineParsing, _playbackLineNum);
@@ -913,12 +924,12 @@ void SessionRecording::readTimeKeyframeBinary(timestamps& times,
void SessionRecording::readTimeKeyframeAscii(timestamps& times,
datamessagestructures::TimeKeyframe& kf,
std::string filenameRead,
std::string currentParsingLine,
int lineN)
{
std::string entryType;
std::istringstream iss(filenameRead);
std::istringstream iss(currentParsingLine);
iss >> entryType;
iss >> times.timeOs >> times.timeRec >> times.timeSim;
kf.read(iss);
@@ -931,8 +942,8 @@ void SessionRecording::readTimeKeyframeAscii(timestamps& times,
}
}
static std::string SessionRecording::readHeaderElement(std::ifstream& stream,
size_t readLen_chars)
std::string SessionRecording::readHeaderElement(std::ifstream& stream,
size_t readLen_chars)
{
std::vector<char> readTemp(readLen_chars);
stream.read(&readTemp[0], readLen_chars);
@@ -943,7 +954,7 @@ void SessionRecording::playbackScript() {
timestamps times;
datamessagestructures::ScriptMessage kf;
if (_recordingDataMode == RecordedDataMode::Binary) {
if (_recordingDataMode == SessionRecordingDataMode::Binary) {
readScriptKeyframeBinary(times, kf, _playbackFile, _playbackLineNum);
} else {
readScriptKeyframeAscii(times, kf, _playbackLineParsing, _playbackLineNum);
@@ -990,11 +1001,11 @@ void SessionRecording::readScriptKeyframeBinary(timestamps& times,
void SessionRecording::readScriptKeyframeAscii(timestamps& times,
datamessagestructures::ScriptMessage& kf,
std::string filenameRead,
std::string currentParsingLine,
int lineN)
{
std::string entryType;
std::istringstream iss(filenameRead);
std::istringstream iss(currentParsingLine);
iss >> entryType;
iss >> times.timeOs >> times.timeRec >> times.timeSim;
kf.read(iss);
@@ -1156,11 +1167,6 @@ bool SessionRecording::doesTimelineEntryContainCamera(unsigned int index) const
}
bool SessionRecording::processNextNonCameraKeyframeAheadInTime() {
//LINFO(fmt::format(
// "Keyframe at {} frame={} timelineIndex={}",
// now, global::renderEngine._frameNumber, _idxTimeline
//));
switch (getNextKeyframeType()) {
case RecordedType::Camera:
// Just return true since this function no longer handles camera keyframes

View File

@@ -40,7 +40,7 @@ int startRecording(lua_State* L) {
return luaL_error(L, "filepath string is empty");
}
global::sessionRecording.setRecordDataFormat(
openspace::interaction::SessionRecording::RecordedDataMode::Binary
openspace::interaction::SessionRecordingDataMode::Binary
);
global::sessionRecording.startRecording(recordFilePath);
@@ -63,7 +63,7 @@ int startRecordingAscii(lua_State* L) {
return luaL_error(L, "filepath string is empty");
}
global::sessionRecording.setRecordDataFormat(
openspace::interaction::SessionRecording::RecordedDataMode::Ascii
openspace::interaction::SessionRecordingDataMode::Ascii
);
global::sessionRecording.startRecording(recordFilePath);

View File

@@ -51,11 +51,11 @@ ConvertRecFormatTask::ConvertRecFormatTask(const ghoul::Dictionary& dictionary)
ghoul_assert(FileSys.fileExists(_inFilePath), "The filename must exist");
if (!FileSys.fileExists(_inFilePath)) {
LERROR(fmt::format("Failed to load session recording file: {}", _inFilePath));
//throw ghoul::FileNotFoundError(_inFilePath);
}
_iFile.exceptions(std::ofstream::failbit | std::ofstream::badbit);
_iFile.open(_inFilePath);
else {
_iFile.open(_inFilePath, std::ifstream::in);
determineFormatType();
}
}
ConvertRecFormatTask::~ConvertRecFormatTask() {
@@ -63,17 +63,42 @@ ConvertRecFormatTask::~ConvertRecFormatTask() {
_oFile.close();
}
void ConvertRecFormatTask::perform(const Task::ProgressCallback& progressCallback) {
std::string ConvertRecFormatTask::description() {
std::string description = "Convert session recording file '" + _inFilePath + "' ";
if (_fileFormatType == SessionRecordingDataMode::Ascii) {
description += "(ascii format) ";
}
else if (_fileFormatType == SessionRecordingDataMode::Binary) {
description += "(binary format) ";
}
else {
description += "(UNKNOWN format) ";
}
description += "conversion to file '" + _outFilePath + "'.";
return description;
}
void ConvertRecFormatTask::perform(const Task::ProgressCallback& progressCallback) {
convert();
}
void ConvertRecFormatTask::convert() {
SessionRecording::RecordedDataMode type = formatType();
if (_fileFormatType == SessionRecordingDataMode::Ascii) {
_oFile.open(_outFilePath);
}
else if (_fileFormatType == SessionRecordingDataMode::Binary) {
_oFile.open(_outFilePath, std::ios::binary);
}
_oFile.write(SessionRecordingFileHeaderTitle.c_str(),
SessionRecordingFileHeaderTitle.length());
_oFile.write(SessionRecording::FileHeaderVersion,
SessionRecording::FileHeaderVersionLength);
_oFile.close();
if (type == SessionRecording::RecordedDataMode::Ascii) {
if (_fileFormatType == SessionRecordingDataMode::Ascii) {
convertToBinary();
}
else if (type == SessionRecording::RecordedDataMode::Binary) {
else if (_fileFormatType == SessionRecordingDataMode::Binary) {
convertToAscii();
}
else {
@@ -82,27 +107,31 @@ void ConvertRecFormatTask::convert() {
}
}
SessionRecording::RecordedDataMode ConvertRecFormatTask::formatType() {
const std::string expectedHeader = "OpenSpace_record/playback";
void ConvertRecFormatTask::determineFormatType() {
_fileFormatType = SessionRecordingDataMode::Unknown;
std::string line;
//Get first line, which is ASCII regardless of format
std::getline(_iFile, line);
if (line.substr(0, SessionRecording::FileHeaderTitle.length())
!= SessionRecording::FileHeaderTitle)
line = SessionRecording::readHeaderElement(_iFile,
SessionRecordingFileHeaderTitle.length());
if (line.substr(0, SessionRecordingFileHeaderTitle.length())
!= SessionRecordingFileHeaderTitle)
{
LERROR(fmt::format("Session recording file {} does not have expected header.", _inFilePath));
return SessionRecording::RecordedDataMode::Binary + 1;
LERROR(fmt::format("Session recording file {} does not have expected header.",
_inFilePath));
}
else {
if (line.back() == SessionRecording::DataFormatAsciiTag) {
return SessionRecording::RecordedDataMode::Ascii;
//Read version string and throw it away (and also line feed character at end)
SessionRecording::readHeaderElement(_iFile,
SessionRecording::FileHeaderVersionLength);
line = SessionRecording::readHeaderElement(_iFile, 1);
SessionRecording::readHeaderElement(_iFile, 1);
if (line.at(0) == SessionRecording::DataFormatAsciiTag) {
_fileFormatType = SessionRecordingDataMode::Ascii;
}
else if (line.back() == SessionRecording::DataFormatBinaryTag) {
return SessionRecording::RecordedDataMode::Binary;
}
else {
return SessionRecording::RecordedDataMode::Binary + 1;
else if (line.at(0) == SessionRecording::DataFormatBinaryTag) {
_fileFormatType = SessionRecordingDataMode::Binary;
}
}
}
@@ -114,8 +143,10 @@ void ConvertRecFormatTask::convertToAscii() {
datamessagestructures::ScriptMessage skf;
int lineNum = 1;
unsigned char frameType;
_outFilePath = addFileSuffix(_inFilePath, "_ascii");
std::stringstream keyframeLine = std::stringstream();
_oFile.open(_outFilePath, std::ifstream::app);
char tmpType = SessionRecording::DataFormatAsciiTag;
_oFile.write(&tmpType, 1);
_oFile.write("\n", 1);
bool fileReadOk = true;
while (fileReadOk) {
@@ -130,20 +161,24 @@ void ConvertRecFormatTask::convertToAscii() {
break;
}
std::stringstream keyframeLine = std::stringstream();
keyframeLine.str(std::string());
if (frameType == 'c') {
if (frameType == SessionRecordingHeaderCameraBinary) {
SessionRecording::readCameraKeyframeBinary(times, ckf, _iFile, lineNum);
SessionRecording::saveHeaderAscii(times, "camera", keyframeLine);
SessionRecording::saveHeaderAscii(times, SessionRecordingHeaderCameraAscii,
keyframeLine);
ckf.write(keyframeLine);
}
else if (frameType == 't') {
else if (frameType == SessionRecordingHeaderTimeBinary) {
SessionRecording::readTimeKeyframeBinary(times, tkf, _iFile, lineNum);
SessionRecording::saveHeaderAscii(times, "time", keyframeLine);
SessionRecording::saveHeaderAscii(times, SessionRecordingHeaderTimeAscii,
keyframeLine);
tkf.write(keyframeLine);
}
else if (frameType == 's') {
else if (frameType == SessionRecordingHeaderScriptBinary) {
SessionRecording::readScriptKeyframeBinary(times, skf, _iFile, lineNum);
SessionRecording::saveHeaderAscii(times, "script", keyframeLine);
SessionRecording::saveHeaderAscii(times, SessionRecordingHeaderScriptAscii,
keyframeLine);
skf.write(keyframeLine);
}
else {
@@ -156,6 +191,7 @@ void ConvertRecFormatTask::convertToAscii() {
SessionRecording::saveKeyframeToFile(keyframeLine.str(), _oFile);
lineNum++;
}
_oFile.close();
}
void ConvertRecFormatTask::convertToBinary() {
@@ -166,8 +202,10 @@ void ConvertRecFormatTask::convertToBinary() {
int lineNum = 1;
std::string lineContents;
unsigned char keyframeBuffer[SessionRecording::_saveBufferMaxSize_bytes];
std::ofstream saveFile;
saveFile.open(_outFilePath, std::ios::binary);
_oFile.open(_outFilePath, std::ifstream::app | std::ios::binary);
char tmpType = SessionRecording::DataFormatBinaryTag;
_oFile.write(&tmpType, 1);
_oFile.write("\n", 1);
size_t idx = 0;
while (std::getline(_iFile, lineContents)) {
@@ -183,20 +221,20 @@ void ConvertRecFormatTask::convertToBinary() {
break;
}
if (entryType == "camera") {
SessionRecording::readCameraKeyframeAscii(times, ckf, _inFilePath, lineNum);
if (entryType == SessionRecordingHeaderCameraAscii) {
SessionRecording::readCameraKeyframeAscii(times, ckf, lineContents, lineNum);
SessionRecording::saveCameraKeyframeBinary(times, ckf, keyframeBuffer,
saveFile);
_oFile);
}
else if (entryType == "time") {
SessionRecording::readTimeKeyframeAscii(times, tkf, _inFilePath, lineNum);
else if (entryType == SessionRecordingHeaderTimeAscii) {
SessionRecording::readTimeKeyframeAscii(times, tkf, lineContents, lineNum);
SessionRecording::saveTimeKeyframeBinary(times, tkf, keyframeBuffer,
saveFile);
_oFile);
}
else if (entryType == "script") {
SessionRecording::readScriptKeyframeAscii(times, skf, _inFilePath, lineNum);
else if (entryType == SessionRecordingHeaderScriptAscii) {
SessionRecording::readScriptKeyframeAscii(times, skf, lineContents, lineNum);
SessionRecording::saveScriptKeyframeBinary(times, skf, keyframeBuffer,
saveFile);
_oFile);
}
else {
LERROR(fmt::format(
@@ -206,7 +244,7 @@ void ConvertRecFormatTask::convertToBinary() {
break;
}
}
saveFile.close();
_oFile.close();
LINFO(fmt::format(
"Finished converting {} entries from file {}",
lineNum, _inFilePath