removed readOnlyMeta (was not really in use)
This commit is contained in:
parent
12b0d9a930
commit
e8d1578a33
3 changed files with 85 additions and 652 deletions
56
lib/dtsc.cpp
56
lib/dtsc.cpp
|
@ -645,11 +645,13 @@ DTSC::File::File(std::string filename, bool create) {
|
|||
currframe = 0;
|
||||
}
|
||||
|
||||
|
||||
/// Returns the header metadata for this file as JSON::Value.
|
||||
DTSC::readOnlyMeta & DTSC::File::getMeta() {
|
||||
DTSC::Meta & DTSC::File::getMeta() {
|
||||
return metadata;
|
||||
}
|
||||
|
||||
|
||||
/// (Re)writes the given string to the header area if the size is the same as the existing header.
|
||||
/// Forces a write if force is set to true.
|
||||
bool DTSC::File::writeHeader(std::string & header, bool force) {
|
||||
|
@ -704,30 +706,30 @@ void DTSC::File::readHeader(int pos) {
|
|||
} else {
|
||||
DEBUG_MSG(DLVL_ERROR, "Could not read header @ %d", pos);
|
||||
}
|
||||
metadata = readOnlyMeta();
|
||||
metadata = Meta();
|
||||
return;
|
||||
}
|
||||
if (memcmp(buffer, DTSC::Magic_Header, 4) != 0) {
|
||||
DEBUG_MSG(DLVL_ERROR, "Invalid header - %.4s != %.4s @ %i", (char *)buffer, DTSC::Magic_Header, pos);
|
||||
metadata = readOnlyMeta();
|
||||
metadata = Meta();
|
||||
return;
|
||||
}
|
||||
if (fread(buffer, 4, 1, F) != 1) {
|
||||
DEBUG_MSG(DLVL_ERROR, "Could not read header size @ %i", pos);
|
||||
metadata = readOnlyMeta();
|
||||
metadata = Meta();
|
||||
return;
|
||||
}
|
||||
long packSize = ntohl(((unsigned long *)buffer)[0]);
|
||||
long packSize = ntohl(((unsigned long *)buffer)[0]) + 8;
|
||||
std::string strBuffer;
|
||||
strBuffer.resize(packSize);
|
||||
if (packSize) {
|
||||
fseek(F, pos, SEEK_SET);
|
||||
if (fread((void *)strBuffer.c_str(), packSize, 1, F) != 1) {
|
||||
DEBUG_MSG(DLVL_ERROR, "Could not read header packet @ %i", pos);
|
||||
metadata = readOnlyMeta();
|
||||
metadata = Meta();
|
||||
return;
|
||||
}
|
||||
JSON::fromDTMI(strBuffer, metaStorage);
|
||||
metadata = readOnlyMeta(metaStorage);//make readonly
|
||||
metadata = Meta(DTSC::Packet(strBuffer.data(), strBuffer.size(),true));
|
||||
}
|
||||
//if there is another header, read it and replace metadata with that one.
|
||||
if (metadata.moreheader) {
|
||||
|
@ -836,7 +838,7 @@ void DTSC::File::seekNext() {
|
|||
insert = true;
|
||||
} else {
|
||||
long tid = myPack.getTrackId();
|
||||
for (unsigned int i = 0; i != metadata.tracks[tid].keyLen; i++) {
|
||||
for (unsigned int i = 0; i != metadata.tracks[tid].keys.size(); i++) {
|
||||
if ((unsigned long long)metadata.tracks[tid].keys[i].getTime() > myPack.getTime()) {
|
||||
tmpPos.seekTime = metadata.tracks[tid].keys[i].getTime();
|
||||
tmpPos.bytePos = metadata.tracks[tid].keys[i].getBpos();
|
||||
|
@ -965,8 +967,8 @@ bool DTSC::File::seek_time(unsigned int ms, unsigned int trackNo, bool forceSeek
|
|||
tmpPos.bytePos = 0;
|
||||
tmpPos.seekTime = 0;
|
||||
}
|
||||
DTSC::readOnlyTrack & trackRef = metadata.tracks[trackNo];
|
||||
for (unsigned int i = 0; i < trackRef.keyLen; i++) {
|
||||
DTSC::Track & trackRef = metadata.tracks[trackNo];
|
||||
for (unsigned int i = 0; i < trackRef.keys.size(); i++) {
|
||||
long keyTime = trackRef.keys[i].getTime();
|
||||
if (keyTime > ms) {
|
||||
break;
|
||||
|
@ -1066,8 +1068,8 @@ bool DTSC::File::atKeyframe() {
|
|||
return true;
|
||||
}
|
||||
long long int bTime = myPack.getTime();
|
||||
DTSC::readOnlyTrack & trackRef = metadata.tracks[myPack.getTrackId()];
|
||||
for (unsigned int i = 0; i < trackRef.keyLen; i++) {
|
||||
DTSC::Track & trackRef = metadata.tracks[myPack.getTrackId()];
|
||||
for (unsigned int i = 0; i < trackRef.keys.size(); i++) {
|
||||
if (trackRef.keys[i].getTime() >= bTime) {
|
||||
return (trackRef.keys[i].getTime() == bTime);
|
||||
}
|
||||
|
@ -1089,31 +1091,3 @@ DTSC::File::~File() {
|
|||
}
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
|
||||
bool DTSC::isFixed(JSON::Value & metadata) {
|
||||
if (metadata.isMember("is_fixed")) {
|
||||
return true;
|
||||
}
|
||||
if (!metadata.isMember("tracks")) {
|
||||
return false;
|
||||
}
|
||||
for (JSON::ObjIter it = metadata["tracks"].ObjBegin(); it != metadata["tracks"].ObjEnd(); it++) {
|
||||
if (it->second["type"].asString() == "meta") {
|
||||
continue;
|
||||
}
|
||||
if (!it->second["keys"].isString()) {
|
||||
return false;
|
||||
}
|
||||
//Check for bpos: last element bpos != 0
|
||||
std::string keyRef = it->second["keys"].asStringRef();
|
||||
if (keyRef.size() < 16) {
|
||||
return false;
|
||||
}
|
||||
int offset = keyRef.size() - 17;
|
||||
if (!(keyRef[offset] | keyRef[offset + 1] | keyRef[offset + 2] | keyRef[offset + 3] | keyRef[offset + 4])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
98
lib/dtsc.h
98
lib/dtsc.h
|
@ -20,7 +20,6 @@
|
|||
#define DTSC_CON 0xFF
|
||||
|
||||
namespace DTSC {
|
||||
bool isFixed(JSON::Value & metadata);
|
||||
|
||||
///\brief This enum holds all possible datatypes for DTSC packets.
|
||||
enum datatype {
|
||||
|
@ -252,27 +251,33 @@ namespace DTSC {
|
|||
char data[11];
|
||||
};
|
||||
|
||||
///\brief Basic class for storage of a read-only track
|
||||
class readOnlyTrack {
|
||||
///\brief Class for storage of track data
|
||||
class Track {
|
||||
public:
|
||||
readOnlyTrack();
|
||||
readOnlyTrack(JSON::Value & trackRef);
|
||||
Track();
|
||||
Track(JSON::Value & trackRef);
|
||||
Track(Scan & trackRef);
|
||||
|
||||
inline operator bool() const {
|
||||
return (partLen && keySizes.size() && (keySizes.size() == keyLen));
|
||||
return (parts.size() && keySizes.size() && (keySizes.size() == keys.size()));
|
||||
}
|
||||
void update(long long packTime, long long packOffset, long long packDataSize, long long packBytePos, bool isKeyframe, long long packSendSize, unsigned long segment_size = 5000);
|
||||
int getSendLen();
|
||||
void send(Socket::Connection & conn);
|
||||
void writeTo(char *& p);
|
||||
JSON::Value toJSON();
|
||||
std::deque<Fragment> fragments;
|
||||
std::deque<Key> keys;
|
||||
std::deque<unsigned long> keySizes;
|
||||
std::deque<Part> parts;
|
||||
Key & getKey(unsigned int keyNum);
|
||||
unsigned int timeToKeynum(unsigned int timestamp);
|
||||
unsigned int timeToFragnum(unsigned int timestamp);
|
||||
void reset();
|
||||
void toPrettyString(std::ostream & str, int indent = 0, int verbosity = 0);
|
||||
|
||||
std::string getIdentifier();
|
||||
std::string getWritableIdentifier();
|
||||
JSON::Value toJSON();
|
||||
long long unsigned int fragLen;
|
||||
Fragment * fragments;
|
||||
long long unsigned int keyLen;
|
||||
Key * keys;
|
||||
std::vector<unsigned long> keySizes;
|
||||
long long unsigned int partLen;
|
||||
Part * parts;
|
||||
unsigned int trackID;
|
||||
unsigned long long firstms;
|
||||
unsigned long long lastms;
|
||||
|
@ -289,62 +294,19 @@ namespace DTSC {
|
|||
int width;
|
||||
int height;
|
||||
int fpks;
|
||||
void toPrettyString(std::ostream & str, int indent = 0, int verbosity = 0);
|
||||
};
|
||||
|
||||
///\brief Class for storage of track data
|
||||
class Track : public readOnlyTrack {
|
||||
public:
|
||||
Track();
|
||||
Track(const readOnlyTrack & rhs);
|
||||
Track(JSON::Value & trackRef);
|
||||
Track(Scan & trackRef);
|
||||
inline operator bool() const {
|
||||
return (parts.size() && keySizes.size() && (keySizes.size() == keys.size()));
|
||||
}
|
||||
void update(long long packTime, long long packOffset, long long packDataSize, long long packBytePos, bool isKeyframe, long long packSendSize, unsigned long segment_size = 5000);
|
||||
int getSendLen();
|
||||
void send(Socket::Connection & conn);
|
||||
void writeTo(char *& p);
|
||||
JSON::Value toJSON();
|
||||
std::deque<Fragment> fragments;
|
||||
std::deque<Key> keys;
|
||||
std::deque<unsigned long> keySizes;
|
||||
std::deque<Part> parts;
|
||||
Key & getKey(unsigned int keyNum);
|
||||
void reset();
|
||||
void toPrettyString(std::ostream & str, int indent = 0, int verbosity = 0);
|
||||
};
|
||||
|
||||
///\brief Class for storage of read-only meta data
|
||||
class readOnlyMeta {
|
||||
public:
|
||||
readOnlyMeta();
|
||||
readOnlyMeta(JSON::Value & meta);
|
||||
inline operator bool() const {
|
||||
return vod || live;
|
||||
}
|
||||
std::map<unsigned int, readOnlyTrack> tracks;
|
||||
bool vod;
|
||||
bool live;
|
||||
bool merged;
|
||||
long long int moreheader;
|
||||
long long int bufferWindow;
|
||||
unsigned int getSendLen();
|
||||
void send(Socket::Connection & conn);
|
||||
void writeTo(char * p);
|
||||
JSON::Value toJSON();
|
||||
bool isFixed();
|
||||
void toPrettyString(std::ostream & str, int indent = 0, int verbosity = 0);
|
||||
};
|
||||
|
||||
///\brief Class for storage of meta data
|
||||
class Meta : public readOnlyMeta {
|
||||
class Meta{
|
||||
/// \todo Make toJSON().toNetpacked() shorter
|
||||
public:
|
||||
Meta();
|
||||
Meta(const DTSC::Packet & source);
|
||||
Meta(const readOnlyMeta & meta);
|
||||
Meta(JSON::Value & meta);
|
||||
|
||||
inline operator bool() const { //returns if the object contains valid meta data BY LOOKING AT vod/live FLAGS
|
||||
return vod || live;
|
||||
}
|
||||
void reinit(const DTSC::Packet & source);
|
||||
void update(DTSC::Packet & pack, unsigned long segment_size = 5000);
|
||||
void updatePosOverride(DTSC::Packet & pack, unsigned long bpos);
|
||||
|
@ -355,10 +317,14 @@ namespace DTSC {
|
|||
void writeTo(char * p);
|
||||
JSON::Value toJSON();
|
||||
void reset();
|
||||
bool isFixed();
|
||||
void toPrettyString(std::ostream & str, int indent = 0, int verbosity = 0);
|
||||
//members:
|
||||
std::map<unsigned int, Track> tracks;
|
||||
bool vod;
|
||||
bool live;
|
||||
bool merged;
|
||||
long long int moreheader;
|
||||
long long int bufferWindow;
|
||||
};
|
||||
|
||||
/// A simple wrapper class that will open a file and allow easy reading/writing of DTSC data from/to it.
|
||||
|
@ -370,7 +336,7 @@ namespace DTSC {
|
|||
File & operator = (const File & rhs);
|
||||
operator bool() const;
|
||||
~File();
|
||||
readOnlyMeta & getMeta();
|
||||
Meta & getMeta();
|
||||
long long int getLastReadPos();
|
||||
bool writeHeader(std::string & header, bool force = false);
|
||||
long long int addHeader(std::string & header);
|
||||
|
@ -393,7 +359,7 @@ namespace DTSC {
|
|||
void readHeader(int pos);
|
||||
DTSC::Packet myPack;
|
||||
JSON::Value metaStorage;
|
||||
readOnlyMeta metadata;
|
||||
Meta metadata;
|
||||
std::map<unsigned int, std::string> trackMapping;
|
||||
long long int currtime;
|
||||
long long int lastreadpos;
|
||||
|
|
583
lib/dtscmeta.cpp
583
lib/dtscmeta.cpp
|
@ -949,75 +949,6 @@ namespace DTSC {
|
|||
str << std::string(indent, ' ') << "Fragment " << getNumber() << ": Dur(" << getDuration() << "), Len(" << (int)getLength() << "), Size(" << getSize() << ")" << std::endl;
|
||||
}
|
||||
|
||||
///\brief Constructs an empty readOnlyTrack
|
||||
readOnlyTrack::readOnlyTrack() {
|
||||
fragments = NULL;
|
||||
fragLen = 0;
|
||||
keys = NULL;
|
||||
keyLen = 0;
|
||||
parts = NULL;
|
||||
partLen = 0;
|
||||
missedFrags = 0;
|
||||
firstms = 0;
|
||||
lastms = 0;
|
||||
bps = 0;
|
||||
rate = 0;
|
||||
size = 0;
|
||||
channels = 0;
|
||||
width = 0;
|
||||
height = 0;
|
||||
fpks = 0;
|
||||
}
|
||||
|
||||
///\brief Constructs a readOnlyTrack from a JSON::Value
|
||||
readOnlyTrack::readOnlyTrack(JSON::Value & trackRef) {
|
||||
if (trackRef.isMember("fragments") && trackRef["fragments"].isString()) {
|
||||
fragments = (Fragment *)trackRef["fragments"].asStringRef().data();
|
||||
fragLen = trackRef["fragments"].asStringRef().size() / 11;
|
||||
} else {
|
||||
fragments = 0;
|
||||
fragLen = 0;
|
||||
}
|
||||
if (trackRef.isMember("keys") && trackRef["keys"].isString()) {
|
||||
keys = (Key *)trackRef["keys"].asStringRef().data();
|
||||
keyLen = trackRef["keys"].asStringRef().size() / 16;
|
||||
} else {
|
||||
keys = 0;
|
||||
keyLen = 0;
|
||||
}
|
||||
if (trackRef.isMember("parts") && trackRef["parts"].isString()) {
|
||||
parts = (Part *)trackRef["parts"].asStringRef().data();
|
||||
partLen = trackRef["parts"].asStringRef().size() / 9;
|
||||
} else {
|
||||
parts = 0;
|
||||
partLen = 0;
|
||||
}
|
||||
trackID = trackRef["trackid"].asInt();
|
||||
firstms = trackRef["firstms"].asInt();
|
||||
lastms = trackRef["lastms"].asInt();
|
||||
bps = trackRef["bps"].asInt();
|
||||
missedFrags = trackRef["missed_frags"].asInt();
|
||||
codec = trackRef["codec"].asStringRef();
|
||||
type = trackRef["type"].asStringRef();
|
||||
init = trackRef["init"].asStringRef();
|
||||
if (type == "audio") {
|
||||
rate = trackRef["rate"].asInt();
|
||||
size = trackRef["size"].asInt();
|
||||
channels = trackRef["channels"].asInt();
|
||||
}
|
||||
if (type == "video") {
|
||||
width = trackRef["width"].asInt();
|
||||
height = trackRef["height"].asInt();
|
||||
fpks = trackRef["fpks"].asInt();
|
||||
}
|
||||
if (trackRef.isMember("keysizes") && trackRef["keysizes"].isString()) {
|
||||
std::string tmp = trackRef["keysizes"].asStringRef();
|
||||
for (unsigned int i = 0; i < tmp.size(); i += 4){
|
||||
keySizes.push_back((((long unsigned)tmp[i]) << 24) | (((long unsigned)tmp[i+1]) << 16) | (((long unsigned int)tmp[i+2]) << 8) | tmp[i+3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///\brief Constructs an empty track
|
||||
Track::Track() {
|
||||
trackID = 0;
|
||||
|
@ -1033,36 +964,6 @@ namespace DTSC {
|
|||
fpks = 0;
|
||||
}
|
||||
|
||||
///\brief Constructs a track from a readOnlyTrack
|
||||
Track::Track(const readOnlyTrack & rhs) {
|
||||
trackID = rhs.trackID;
|
||||
firstms = rhs.firstms;
|
||||
lastms = rhs.lastms;
|
||||
bps = rhs.bps;
|
||||
missedFrags = rhs.missedFrags;
|
||||
init = rhs.init;
|
||||
codec = rhs.codec;
|
||||
type = rhs.type;
|
||||
rate = rhs.rate;
|
||||
size = rhs.size;
|
||||
channels = rhs.channels;
|
||||
width = rhs.width;
|
||||
height = rhs.height;
|
||||
fpks = rhs.fpks;
|
||||
if (rhs.fragments && rhs.fragLen) {
|
||||
fragments = std::deque<Fragment>(rhs.fragments, rhs.fragments + rhs.fragLen);
|
||||
}
|
||||
if (rhs.keys && rhs.keyLen) {
|
||||
keys = std::deque<Key>(rhs.keys, rhs.keys + rhs.keyLen);
|
||||
}
|
||||
if (rhs.parts && rhs.partLen) {
|
||||
parts = std::deque<Part>(rhs.parts, rhs.parts + rhs.partLen);
|
||||
}
|
||||
for(std::vector<long unsigned>::const_iterator it = rhs.keySizes.begin(); it != rhs.keySizes.end(); it++){
|
||||
keySizes.push_back(*it);
|
||||
}
|
||||
}
|
||||
|
||||
///\brief Constructs a track from a JSON::Value
|
||||
Track::Track(JSON::Value & trackRef) {
|
||||
if (trackRef.isMember("fragments") && trackRef["fragments"].isString()) {
|
||||
|
@ -1225,30 +1126,26 @@ namespace DTSC {
|
|||
return keys[keyNum - keys[0].getNumber()];
|
||||
}
|
||||
|
||||
///\brief Returns a unique identifier for a track
|
||||
std::string readOnlyTrack::getIdentifier() {
|
||||
std::stringstream result;
|
||||
if (type == "") {
|
||||
result << "metadata_" << trackID;
|
||||
return result.str();
|
||||
unsigned int Track::timeToKeynum(unsigned int timestamp){
|
||||
unsigned int result = 0;
|
||||
for (std::deque<Key>::iterator it = keys.begin(); it != keys.end(); it++){
|
||||
if (it->getTime() >= timestamp){
|
||||
break;
|
||||
}
|
||||
result = it->getNumber();
|
||||
}
|
||||
result << type << "_";
|
||||
result << codec << "_";
|
||||
if (type == "audio") {
|
||||
result << channels << "ch_";
|
||||
result << rate << "hz";
|
||||
} else if (type == "video") {
|
||||
result << width << "x" << height << "_";
|
||||
result << (double)fpks / 1000 << "fps";
|
||||
}
|
||||
return result.str();
|
||||
return result;
|
||||
}
|
||||
|
||||
///\brief Returns a writable identifier for a track, to prevent overwrites on readout
|
||||
std::string readOnlyTrack::getWritableIdentifier() {
|
||||
std::stringstream result;
|
||||
result << getIdentifier() << "_" << trackID;
|
||||
return result.str();
|
||||
unsigned int Track::timeToFragnum(unsigned int timestamp){
|
||||
unsigned long long int totalTime = firstms;
|
||||
for (unsigned int i = 0; i<fragments.size(); i++){
|
||||
if (timestamp <= totalTime){
|
||||
return i;
|
||||
}
|
||||
totalTime += fragments[i].getDuration();
|
||||
}
|
||||
return fragments.size()-1;
|
||||
}
|
||||
|
||||
///\brief Resets a track, clears all meta values
|
||||
|
@ -1262,92 +1159,6 @@ namespace DTSC {
|
|||
lastms = 0;
|
||||
}
|
||||
|
||||
///\brief Creates an empty read-only meta object
|
||||
readOnlyMeta::readOnlyMeta() {
|
||||
vod = false;
|
||||
live = false;
|
||||
merged = false;
|
||||
moreheader = 0;
|
||||
merged = false;
|
||||
bufferWindow = 0;
|
||||
}
|
||||
|
||||
///\brief Creates a read-only meta object from a given JSON::Value
|
||||
readOnlyMeta::readOnlyMeta(JSON::Value & meta) {
|
||||
vod = meta.isMember("vod") && meta["vod"];
|
||||
live = meta.isMember("live") && meta["live"];
|
||||
merged = meta.isMember("merged") && meta["merged"];
|
||||
bufferWindow = 0;
|
||||
if (meta.isMember("buffer_window")) {
|
||||
bufferWindow = meta["buffer_window"].asInt();
|
||||
}
|
||||
for (JSON::ObjIter it = meta["tracks"].ObjBegin(); it != meta["tracks"].ObjEnd(); it++) {
|
||||
if (it->second.isMember("trackid") && it->second["trackid"]) {
|
||||
tracks[it->second["trackid"].asInt()] = readOnlyTrack(it->second);
|
||||
}
|
||||
}
|
||||
if (meta.isMember("moreheader")) {
|
||||
moreheader = meta["moreheader"].asInt();
|
||||
} else {
|
||||
moreheader = 0;
|
||||
}
|
||||
}
|
||||
|
||||
///\brief Converts a read-only track to a human readable string
|
||||
///\param str The stringstream to append to
|
||||
///\param indent the amount of indentation needed
|
||||
///\param verbosity How verbose the output needs to be
|
||||
void readOnlyTrack::toPrettyString(std::ostream & str, int indent, int verbosity) {
|
||||
str << std::string(indent, ' ') << "Track " << getWritableIdentifier() << std::endl;
|
||||
str << std::string(indent + 2, ' ') << "ID: " << trackID << std::endl;
|
||||
str << std::string(indent + 2, ' ') << "Firstms: " << firstms << std::endl;
|
||||
str << std::string(indent + 2, ' ') << "Lastms: " << lastms << std::endl;
|
||||
str << std::string(indent + 2, ' ') << "Bps: " << bps << std::endl;
|
||||
if (missedFrags) {
|
||||
str << std::string(indent + 2, ' ') << "missedFrags: " << missedFrags << std::endl;
|
||||
}
|
||||
str << std::string(indent + 2, ' ') << "Codec: " << codec << std::endl;
|
||||
str << std::string(indent + 2, ' ') << "Type: " << type << std::endl;
|
||||
str << std::string(indent + 2, ' ') << "Init: ";
|
||||
for (unsigned int i = 0; i < init.size(); ++i) {
|
||||
str << std::hex << std::setw(2) << std::setfill('0') << (int)init[i];
|
||||
}
|
||||
str << std::dec << std::endl;
|
||||
if (type == "audio") {
|
||||
str << std::string(indent + 2, ' ') << "Rate: " << rate << std::endl;
|
||||
str << std::string(indent + 2, ' ') << "Size: " << size << std::endl;
|
||||
str << std::string(indent + 2, ' ') << "Channel: " << channels << std::endl;
|
||||
} else if (type == "video") {
|
||||
str << std::string(indent + 2, ' ') << "Width: " << width << std::endl;
|
||||
str << std::string(indent + 2, ' ') << "Height: " << height << std::endl;
|
||||
str << std::string(indent + 2, ' ') << "Fpks: " << fpks << std::endl;
|
||||
}
|
||||
str << std::string(indent + 2, ' ') << "Fragments: " << fragLen << std::endl;
|
||||
if (fragments && verbosity & 0x01) {
|
||||
for (unsigned int i = 0; i < fragLen; i++) {
|
||||
fragments[i].toPrettyString(str, indent + 4);
|
||||
}
|
||||
}
|
||||
str << std::string(indent + 2, ' ') << "Keys: " << keyLen << std::endl;
|
||||
if (keys && verbosity & 0x02) {
|
||||
for (unsigned int i = 0; i < keyLen; i++) {
|
||||
keys[i].toPrettyString(str, indent + 4);
|
||||
}
|
||||
}
|
||||
str << std::string(indent + 2, ' ') << "KeySizes: " << keySizes.size() << std::endl;
|
||||
if (keySizes.size() && verbosity & 0x02){
|
||||
for (unsigned int i = 0; i < keySizes.size(); i++){
|
||||
str << std::string(indent + 4, ' ') << "[" << i << "] " << keySizes[i] << std::endl;
|
||||
}
|
||||
}
|
||||
str << std::string(indent + 2, ' ') << "Parts: " << partLen << std::endl;
|
||||
if (parts && verbosity & 0x04) {
|
||||
for (unsigned int i = 0; i < partLen; i++) {
|
||||
parts[i].toPrettyString(str, indent + 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///\brief Creates an empty meta object
|
||||
Meta::Meta() {
|
||||
vod = false;
|
||||
|
@ -1357,18 +1168,6 @@ namespace DTSC {
|
|||
bufferWindow = 0;
|
||||
}
|
||||
|
||||
///\brief Creates a meta object from a read-only meta object
|
||||
Meta::Meta(const readOnlyMeta & rhs) {
|
||||
vod = rhs.vod;
|
||||
live = rhs.live;
|
||||
merged = rhs.merged;
|
||||
bufferWindow = rhs.bufferWindow;
|
||||
for (std::map<unsigned int, readOnlyTrack>::const_iterator it = rhs.tracks.begin(); it != rhs.tracks.end(); it++) {
|
||||
tracks[it->first] = it->second;
|
||||
}
|
||||
moreheader = rhs.moreheader;
|
||||
}
|
||||
|
||||
Meta::Meta(const DTSC::Packet & source) {
|
||||
reinit(source);
|
||||
}
|
||||
|
@ -1541,24 +1340,31 @@ namespace DTSC {
|
|||
return result;
|
||||
}
|
||||
|
||||
///\brief Determines the "packed" size of a read-only track
|
||||
int readOnlyTrack::getSendLen() {
|
||||
int result = 146 + init.size() + codec.size() + type.size() + getWritableIdentifier().size();
|
||||
result += fragLen * 11;
|
||||
result += keyLen * 16;
|
||||
if (keySizes.size()){
|
||||
result += 11 + (keySizes.size() * 4) + 4;
|
||||
|
||||
///\brief Returns a unique identifier for a track
|
||||
std::string Track::getIdentifier() {
|
||||
std::stringstream result;
|
||||
if (type == "") {
|
||||
result << "metadata_" << trackID;
|
||||
return result.str();
|
||||
}
|
||||
result += partLen * 9;
|
||||
result << type << "_";
|
||||
result << codec << "_";
|
||||
if (type == "audio") {
|
||||
result += 49;
|
||||
result << channels << "ch_";
|
||||
result << rate << "hz";
|
||||
} else if (type == "video") {
|
||||
result += 48;
|
||||
result << width << "x" << height << "_";
|
||||
result << (double)fpks / 1000 << "fps";
|
||||
}
|
||||
if (missedFrags) {
|
||||
result += 23;
|
||||
}
|
||||
return result;
|
||||
return result.str();
|
||||
}
|
||||
|
||||
///\brief Returns a writable identifier for a track, to prevent overwrites on readout
|
||||
std::string Track::getWritableIdentifier() {
|
||||
std::stringstream result;
|
||||
result << getIdentifier() << "_" << trackID;
|
||||
return result.str();
|
||||
}
|
||||
|
||||
///\brief Determines the "packed" size of a track
|
||||
|
@ -1596,135 +1402,6 @@ namespace DTSC {
|
|||
writePointer(p, src.data(), src.size());
|
||||
}
|
||||
|
||||
///\brief Writes a read-only track to a pointer
|
||||
void readOnlyTrack::writeTo(char *& p) {
|
||||
std::string iden = getWritableIdentifier();
|
||||
writePointer(p, convertShort(iden.size()), 2);
|
||||
writePointer(p, iden);
|
||||
writePointer(p, "\340", 1);//Begin track object
|
||||
writePointer(p, "\000\011fragments\002", 12);
|
||||
writePointer(p, convertInt(fragLen * 11), 4);
|
||||
writePointer(p, (char *)fragments, fragLen * 11);
|
||||
writePointer(p, "\000\004keys\002", 7);
|
||||
writePointer(p, convertInt(keyLen * 16), 4);
|
||||
writePointer(p, (char *)keys, keyLen * 16);
|
||||
writePointer(p, "\000\010keysizes\002,", 11);
|
||||
writePointer(p, convertInt(keySizes.size() * 4), 4);
|
||||
std::string tmp;
|
||||
tmp.reserve(keySizes.size() * 4);
|
||||
for (unsigned int i = 0; i < keySizes.size(); i++){
|
||||
tmp += ((char)keySizes[i] >> 24);
|
||||
tmp += ((char)keySizes[i] >> 16);
|
||||
tmp += ((char)keySizes[i] >> 8);
|
||||
tmp += ((char)keySizes[i]);
|
||||
}
|
||||
writePointer(p, tmp.data(), tmp.size());
|
||||
writePointer(p, "\000\005parts\002", 8);
|
||||
writePointer(p, convertInt(partLen * 9), 4);
|
||||
writePointer(p, (char *)parts, partLen * 9);
|
||||
writePointer(p, "\000\007trackid\001", 10);
|
||||
writePointer(p, convertLongLong(trackID), 8);
|
||||
if (missedFrags) {
|
||||
writePointer(p, "\000\014missed_frags\001", 15);
|
||||
writePointer(p, convertLongLong(missedFrags), 8);
|
||||
}
|
||||
writePointer(p, "\000\007firstms\001", 10);
|
||||
writePointer(p, convertLongLong(firstms), 8);
|
||||
writePointer(p, "\000\006lastms\001", 9);
|
||||
writePointer(p, convertLongLong(lastms), 8);
|
||||
writePointer(p, "\000\003bps\001", 6);
|
||||
writePointer(p, convertLongLong(bps), 8);
|
||||
writePointer(p, "\000\004init\002", 7);
|
||||
writePointer(p, convertInt(init.size()), 4);
|
||||
writePointer(p, init);
|
||||
writePointer(p, "\000\005codec\002", 8);
|
||||
writePointer(p, convertInt(codec.size()), 4);
|
||||
writePointer(p, codec);
|
||||
writePointer(p, "\000\004type\002", 7);
|
||||
writePointer(p, convertInt(type.size()), 4);
|
||||
writePointer(p, type);
|
||||
if (type == "audio") {
|
||||
writePointer(p, "\000\004rate\001", 7);
|
||||
writePointer(p, convertLongLong(rate), 8);
|
||||
writePointer(p, "\000\004size\001", 7);
|
||||
writePointer(p, convertLongLong(size), 8);
|
||||
writePointer(p, "\000\010channels\001", 11);
|
||||
writePointer(p, convertLongLong(channels), 8);
|
||||
} else if (type == "video") {
|
||||
writePointer(p, "\000\005width\001", 8);
|
||||
writePointer(p, convertLongLong(width), 8);
|
||||
writePointer(p, "\000\006height\001", 9);
|
||||
writePointer(p, convertLongLong(height), 8);
|
||||
writePointer(p, "\000\004fpks\001", 7);
|
||||
writePointer(p, convertLongLong(fpks), 8);
|
||||
}
|
||||
writePointer(p, "\000\000\356", 3);//End this track Object
|
||||
}
|
||||
|
||||
///\brief Writes a read-only track to a socket
|
||||
void readOnlyTrack::send(Socket::Connection & conn) {
|
||||
conn.SendNow(convertShort(getWritableIdentifier().size()), 2);
|
||||
conn.SendNow(getWritableIdentifier());
|
||||
conn.SendNow("\340", 1);//Begin track object
|
||||
conn.SendNow("\000\011fragments\002", 12);
|
||||
conn.SendNow(convertInt(fragLen * 11), 4);
|
||||
conn.SendNow((char *)fragments, fragLen * 11);
|
||||
conn.SendNow("\000\004keys\002", 7);
|
||||
conn.SendNow(convertInt(keyLen * 16), 4);
|
||||
conn.SendNow((char *)keys, keyLen * 16);
|
||||
conn.SendNow("\000\010keysizes\002,", 11);
|
||||
conn.SendNow(convertInt(keySizes.size() * 4), 4);
|
||||
std::string tmp;
|
||||
tmp.reserve(keySizes.size() * 4);
|
||||
for (unsigned int i = 0; i < keySizes.size(); i++){
|
||||
tmp += ((char)keySizes[i] >> 24);
|
||||
tmp += ((char)keySizes[i] >> 16);
|
||||
tmp += ((char)keySizes[i] >> 8);
|
||||
tmp += ((char)keySizes[i]);
|
||||
}
|
||||
conn.SendNow(tmp.data(), tmp.size());
|
||||
conn.SendNow("\000\005parts\002", 8);
|
||||
conn.SendNow(convertInt(partLen * 9), 4);
|
||||
conn.SendNow((char *)parts, partLen * 9);
|
||||
conn.SendNow("\000\007trackid\001", 10);
|
||||
conn.SendNow(convertLongLong(trackID), 8);
|
||||
if (missedFrags) {
|
||||
conn.SendNow("\000\014missed_frags\001", 15);
|
||||
conn.SendNow(convertLongLong(missedFrags), 8);
|
||||
}
|
||||
conn.SendNow("\000\007firstms\001", 10);
|
||||
conn.SendNow(convertLongLong(firstms), 8);
|
||||
conn.SendNow("\000\006lastms\001", 9);
|
||||
conn.SendNow(convertLongLong(lastms), 8);
|
||||
conn.SendNow("\000\003bps\001", 6);
|
||||
conn.SendNow(convertLongLong(bps), 8);
|
||||
conn.SendNow("\000\004init\002", 7);
|
||||
conn.SendNow(convertInt(init.size()), 4);
|
||||
conn.SendNow(init);
|
||||
conn.SendNow("\000\005codec\002", 8);
|
||||
conn.SendNow(convertInt(codec.size()), 4);
|
||||
conn.SendNow(codec);
|
||||
conn.SendNow("\000\004type\002", 7);
|
||||
conn.SendNow(convertInt(type.size()), 4);
|
||||
conn.SendNow(type);
|
||||
if (type == "audio") {
|
||||
conn.SendNow("\000\004rate\001", 7);
|
||||
conn.SendNow(convertLongLong(rate), 8);
|
||||
conn.SendNow("\000\004size\001", 7);
|
||||
conn.SendNow(convertLongLong(size), 8);
|
||||
conn.SendNow("\000\010channels\001", 11);
|
||||
conn.SendNow(convertLongLong(channels), 8);
|
||||
} else if (type == "video") {
|
||||
conn.SendNow("\000\005width\001", 8);
|
||||
conn.SendNow(convertLongLong(width), 8);
|
||||
conn.SendNow("\000\006height\001", 9);
|
||||
conn.SendNow(convertLongLong(height), 8);
|
||||
conn.SendNow("\000\004fpks\001", 7);
|
||||
conn.SendNow(convertLongLong(fpks), 8);
|
||||
}
|
||||
conn.SendNow("\000\000\356", 3);//End this track Object
|
||||
}
|
||||
|
||||
///\brief Writes a track to a pointer
|
||||
void Track::writeTo(char *& p) {
|
||||
writePointer(p, convertShort(getWritableIdentifier().size()), 2);
|
||||
|
@ -1865,77 +1542,6 @@ namespace DTSC {
|
|||
conn.SendNow("\000\000\356", 3);//End this track Object
|
||||
}
|
||||
|
||||
///\brief Determines the "packed" size of a read-only meta object
|
||||
unsigned int readOnlyMeta::getSendLen() {
|
||||
unsigned int dataLen = 16 + (vod ? 14 : 0) + (live ? 15 : 0) + (merged ? 17 : 0) + (bufferWindow ? 24 : 0) + 21;
|
||||
for (std::map<unsigned int, readOnlyTrack>::iterator it = tracks.begin(); it != tracks.end(); it++) {
|
||||
dataLen += it->second.getSendLen();
|
||||
}
|
||||
return dataLen + 8; //add 8 bytes header length
|
||||
}
|
||||
|
||||
///\brief Writes a read-only meta object to a pointer
|
||||
void readOnlyMeta::writeTo(char * p) {
|
||||
int dataLen = getSendLen() - 8;//strip 8 bytes header
|
||||
writePointer(p, DTSC::Magic_Header, 4);
|
||||
writePointer(p, convertInt(dataLen), 4);
|
||||
writePointer(p, "\340\000\006tracks\340", 10);
|
||||
for (std::map<unsigned int, readOnlyTrack>::iterator it = tracks.begin(); it != tracks.end(); it++) {
|
||||
it->second.writeTo(p);
|
||||
}
|
||||
writePointer(p, "\000\000\356", 3);
|
||||
if (vod) {
|
||||
writePointer(p, "\000\003vod\001", 6);
|
||||
writePointer(p, convertLongLong(1), 8);
|
||||
}
|
||||
if (live) {
|
||||
writePointer(p, "\000\004live\001", 7);
|
||||
writePointer(p, convertLongLong(1), 8);
|
||||
}
|
||||
if (merged) {
|
||||
writePointer(p, "\000\006merged\001", 9);
|
||||
writePointer(p, convertLongLong(1), 8);
|
||||
}
|
||||
if (bufferWindow) {
|
||||
writePointer(p, "\000\015buffer_window\001", 16);
|
||||
writePointer(p, convertLongLong(bufferWindow), 8);
|
||||
}
|
||||
writePointer(p, "\000\012moreheader\001", 13);
|
||||
writePointer(p, convertLongLong(moreheader), 8);
|
||||
writePointer(p, "\000\000\356", 3);//End global object
|
||||
}
|
||||
|
||||
///\brief Writes a read-only meta object to a socket
|
||||
void readOnlyMeta::send(Socket::Connection & conn) {
|
||||
int dataLen = getSendLen() - 8; //strip 8 bytes header
|
||||
conn.SendNow(DTSC::Magic_Header, 4);
|
||||
conn.SendNow(convertInt(dataLen), 4);
|
||||
conn.SendNow("\340\000\006tracks\340", 10);
|
||||
for (std::map<unsigned int, readOnlyTrack>::iterator it = tracks.begin(); it != tracks.end(); it++) {
|
||||
it->second.send(conn);
|
||||
}
|
||||
conn.SendNow("\000\000\356", 3);
|
||||
if (vod) {
|
||||
conn.SendNow("\000\003vod\001", 6);
|
||||
conn.SendNow(convertLongLong(1), 8);
|
||||
}
|
||||
if (live) {
|
||||
conn.SendNow("\000\004live\001", 7);
|
||||
conn.SendNow(convertLongLong(1), 8);
|
||||
}
|
||||
if (merged) {
|
||||
conn.SendNow("\000\006merged\001", 9);
|
||||
conn.SendNow(convertLongLong(1), 8);
|
||||
}
|
||||
if (bufferWindow) {
|
||||
conn.SendNow("\000\015buffer_window\001", 16);
|
||||
conn.SendNow(convertLongLong(bufferWindow), 8);
|
||||
}
|
||||
conn.SendNow("\000\012moreheader\001", 13);
|
||||
conn.SendNow(convertLongLong(moreheader), 8);
|
||||
conn.SendNow("\000\000\356", 3);//End global object
|
||||
}
|
||||
|
||||
///\brief Determines the "packed" size of a meta object
|
||||
unsigned int Meta::getSendLen() {
|
||||
unsigned int dataLen = 16 + (vod ? 14 : 0) + (live ? 15 : 0) + (merged ? 17 : 0) + (bufferWindow ? 24 : 0) + 21;
|
||||
|
@ -2007,51 +1613,6 @@ namespace DTSC {
|
|||
conn.SendNow("\000\000\356", 3);//End global object
|
||||
}
|
||||
|
||||
///\brief Converts a read-only track to a JSON::Value
|
||||
JSON::Value readOnlyTrack::toJSON() {
|
||||
JSON::Value result;
|
||||
if (fragments) {
|
||||
result["fragments"] = std::string((char *)fragments, fragLen * 11);
|
||||
}
|
||||
if (keys) {
|
||||
result["keys"] = std::string((char *)keys, keyLen * 16);
|
||||
}
|
||||
if (keySizes.size()){
|
||||
std::string tmp;
|
||||
tmp.reserve(keySizes.size() * 4);
|
||||
for (unsigned int i = 0; i < keySizes.size(); i++){
|
||||
tmp += ((char)(keySizes[i] >> 24));
|
||||
tmp += ((char)(keySizes[i] >> 16));
|
||||
tmp += ((char)(keySizes[i] >> 8));
|
||||
tmp += ((char)keySizes[i]);
|
||||
}
|
||||
result["keysizes"] = tmp;
|
||||
}
|
||||
if (parts) {
|
||||
result["parts"] = std::string((char *)parts, partLen * 9);
|
||||
}
|
||||
result["trackid"] = trackID;
|
||||
result["firstms"] = (long long)firstms;
|
||||
result["lastms"] = (long long)lastms;
|
||||
result["bps"] = bps;
|
||||
if (missedFrags) {
|
||||
result["missed_frags"] = missedFrags;
|
||||
}
|
||||
result["codec"] = codec;
|
||||
result["type"] = type;
|
||||
result["init"] = init;
|
||||
if (type == "audio") {
|
||||
result["rate"] = rate;
|
||||
result["size"] = size;
|
||||
result["channels"] = channels;
|
||||
} else if (type == "video") {
|
||||
result["width"] = width;
|
||||
result["height"] = height;
|
||||
result["fpks"] = fpks;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
///\brief Converts a track to a JSON::Value
|
||||
JSON::Value Track::toJSON() {
|
||||
JSON::Value result;
|
||||
|
@ -2126,29 +1687,6 @@ namespace DTSC {
|
|||
return result;
|
||||
}
|
||||
|
||||
///\brief Converts a read-only meta object to a human readable string
|
||||
///\param str The stringstream to append to
|
||||
///\param indent the amount of indentation needed
|
||||
///\param verbosity How verbose the output needs to be
|
||||
void readOnlyMeta::toPrettyString(std::ostream & str, int indent, int verbosity) {
|
||||
for (std::map<unsigned int, readOnlyTrack>::iterator it = tracks.begin(); it != tracks.end(); it++) {
|
||||
it->second.toPrettyString(str, indent, verbosity);
|
||||
}
|
||||
if (vod) {
|
||||
str << std::string(indent, ' ') << "Video on Demand" << std::endl;
|
||||
}
|
||||
if (live) {
|
||||
str << std::string(indent, ' ') << "Live" << std::endl;
|
||||
}
|
||||
if (merged) {
|
||||
str << std::string(indent, ' ') << "Merged file" << std::endl;
|
||||
}
|
||||
if (bufferWindow) {
|
||||
str << std::string(indent, ' ') << "Buffer Window: " << bufferWindow << std::endl;
|
||||
}
|
||||
str << std::string(indent, ' ') << "More Header: " << moreheader << std::endl;
|
||||
}
|
||||
|
||||
///\brief Converts a meta object to a human readable string
|
||||
///\param str The stringstream to append to
|
||||
///\param indent the amount of indentation needed
|
||||
|
@ -2172,57 +1710,12 @@ namespace DTSC {
|
|||
str << std::string(indent, ' ') << "More Header: " << moreheader << std::endl;
|
||||
}
|
||||
|
||||
///\brief Converts a read-only meta object to a JSON::Value
|
||||
JSON::Value readOnlyMeta::toJSON() {
|
||||
JSON::Value result;
|
||||
for (std::map<unsigned int, readOnlyTrack>::iterator it = tracks.begin(); it != tracks.end(); it++) {
|
||||
result["tracks"][it->second.getWritableIdentifier()] = it->second.toJSON();
|
||||
}
|
||||
if (vod) {
|
||||
result["vod"] = 1ll;
|
||||
}
|
||||
if (live) {
|
||||
result["live"] = 1ll;
|
||||
}
|
||||
if (merged) {
|
||||
result["merged"] = 1ll;
|
||||
}
|
||||
result["moreheader"] = moreheader;
|
||||
if (bufferWindow) {
|
||||
result["buffer_window"] = bufferWindow;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
///\brief Resets a meta object, removes all unimportant meta values
|
||||
void Meta::reset() {
|
||||
for (std::map<unsigned int, Track>::iterator it = tracks.begin(); it != tracks.end(); it++) {
|
||||
it->second.reset();
|
||||
}
|
||||
}
|
||||
|
||||
///\brief Returns whether a read-only meta object is fixed or not
|
||||
bool readOnlyMeta::isFixed() {
|
||||
for (std::map<unsigned int, readOnlyTrack>::iterator it = tracks.begin(); it != tracks.end(); it++) {
|
||||
if (!it->second.keyLen || !(it->second.keys[it->second.keyLen - 1].getBpos())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
///\brief Returns whether a meta object is fixed or not
|
||||
bool Meta::isFixed() {
|
||||
for (std::map<unsigned int, Track>::iterator it = tracks.begin(); it != tracks.end(); it++) {
|
||||
if (it->second.type == "meta" || it->second.type == "") {
|
||||
continue;
|
||||
}
|
||||
if (!it->second.keys.size() || !(it->second.keys.rbegin()->getBpos())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue