Merge branch 'development' into LTS_development

# Conflicts:
#	lib/dtsc.h
#	lib/dtscmeta.cpp
This commit is contained in:
Thulinma 2016-10-11 16:08:52 +02:00
commit 1db7f2c300
3 changed files with 100 additions and 22 deletions

View file

@ -117,7 +117,7 @@ namespace DTSC {
packType getVersion() const; packType getVersion() const;
void reInit(Socket::Connection & src); void reInit(Socket::Connection & src);
void reInit(const char * data_, unsigned int len, bool noCopy = false); void reInit(const char * data_, unsigned int len, bool noCopy = false);
void genericFill(long long packTime, long long packOffset, long long packTrack, const char * packData, long long packDataSize, long long packBytePos, bool isKeyframe); void genericFill(long long packTime, long long packOffset, long long packTrack, const char * packData, long long packDataSize, uint64_t packBytePos, bool isKeyframe);
void getString(const char * identifier, char *& result, unsigned int & len) const; void getString(const char * identifier, char *& result, unsigned int & len) const;
void getString(const char * identifier, std::string & result) const; void getString(const char * identifier, std::string & result) const;
void getInt(const char * identifier, int & result) const; void getInt(const char * identifier, int & result) const;
@ -282,9 +282,9 @@ namespace DTSC {
return (parts.size() && keySizes.size() && (keySizes.size() == keys.size())); 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); void update(long long packTime, long long packOffset, long long packDataSize, uint64_t packBytePos, bool isKeyframe, long long packSendSize, unsigned long segment_size = 5000);
*/ */
void update(long long packTime, long long packOffset, long long packDataSize, long long packBytePos, bool isKeyframe, long long packSendSize, unsigned long segment_size = 5000, const char * iVec = 0); void update(long long packTime, long long packOffset, long long packDataSize, uint64_t packBytePos, bool isKeyframe, long long packSendSize, unsigned long segment_size = 5000, const char * iVec = 0);
int getSendLen(bool skipDynamic = false); int getSendLen(bool skipDynamic = false);
void send(Socket::Connection & conn, bool skipDynamic = false); void send(Socket::Connection & conn, bool skipDynamic = false);
void writeTo(char *& p); void writeTo(char *& p);
@ -297,7 +297,7 @@ namespace DTSC {
Key & getKey(unsigned int keyNum); Key & getKey(unsigned int keyNum);
Fragment & getFrag(unsigned int fragNum); Fragment & getFrag(unsigned int fragNum);
unsigned int timeToKeynum(unsigned int timestamp); unsigned int timeToKeynum(unsigned int timestamp);
unsigned int timeToFragnum(unsigned int timestamp); uint32_t timeToFragnum(uint64_t timestamp);
void reset(); void reset();
void toPrettyString(std::ostream & str, int indent = 0, int verbosity = 0); void toPrettyString(std::ostream & str, int indent = 0, int verbosity = 0);
void finalize(); void finalize();
@ -342,12 +342,12 @@ namespace DTSC {
} }
void reinit(const DTSC::Packet & source); void reinit(const DTSC::Packet & source);
void update(DTSC::Packet & pack, unsigned long segment_size = 5000); void update(DTSC::Packet & pack, unsigned long segment_size = 5000);
void updatePosOverride(DTSC::Packet & pack, unsigned long bpos); void updatePosOverride(DTSC::Packet & pack, uint64_t bpos);
void update(JSON::Value & pack, unsigned long segment_size = 5000); void update(JSON::Value & pack, unsigned long segment_size = 5000);
/*LTS /*LTS
void update(long long packTime, long long packOffset, long long packTrack, long long packDataSize, long long packBytePos, bool isKeyframe, long long packSendSize = 0, unsigned long segment_size = 5000); void update(long long packTime, long long packOffset, long long packTrack, long long packDataSize, uint64_t packBytePos, bool isKeyframe, long long packSendSize = 0, unsigned long segment_size = 5000);
LTS*/ LTS*/
void update(long long packTime, long long packOffset, long long packTrack, long long packDataSize, long long packBytePos, bool isKeyframe, long long packSendSize = 0, unsigned long segment_size = 5000, const char * iVec = 0); void update(long long packTime, long long packOffset, long long packTrack, long long packDataSize, uint64_t packBytePos, bool isKeyframe, long long packSendSize = 0, unsigned long segment_size = 5000, const char * iVec = 0);
unsigned int getSendLen(bool skipDynamic = false, std::set<unsigned long> selectedTracks = std::set<unsigned long>()); unsigned int getSendLen(bool skipDynamic = false, std::set<unsigned long> selectedTracks = std::set<unsigned long>());
void send(Socket::Connection & conn, bool skipDynamic = false, std::set<unsigned long> selectedTracks = std::set<unsigned long>()); void send(Socket::Connection & conn, bool skipDynamic = false, std::set<unsigned long> selectedTracks = std::set<unsigned long>());
void writeTo(char * p); void writeTo(char * p);
@ -367,6 +367,22 @@ namespace DTSC {
long long int bufferWindow; long long int bufferWindow;
}; };
/// An iterator helper for easily iterating over the parts in a Fragment.
class PartIter {
public:
PartIter(Track & Trk, Fragment & frag);
Part & operator*() const;///< Dereferences into a Value reference.
Part* operator->() const;///< Dereferences into a Value reference.
operator bool() const;///< True if not done iterating.
PartIter & operator++();///<Go to next iteration.
private:
uint32_t lastKey;
uint32_t currInKey;
Track * tRef;
std::deque<Part>::iterator pIt;
std::deque<Key>::iterator kIt;
};
/// A simple wrapper class that will open a file and allow easy reading/writing of DTSC data from/to it. /// A simple wrapper class that will open a file and allow easy reading/writing of DTSC data from/to it.
class File { class File {
public: public:

View file

@ -208,7 +208,7 @@ namespace DTSC {
/// Re-initializes this Packet to contain a generic DTSC packet with the given data fields. /// Re-initializes this Packet to contain a generic DTSC packet with the given data fields.
/// When given a NULL pointer, the data is reserved and memset to 0 /// When given a NULL pointer, the data is reserved and memset to 0
void Packet::genericFill(long long packTime, long long packOffset, long long packTrack, const char * packData, long long packDataSize, long long packBytePos, bool isKeyframe){ void Packet::genericFill(long long packTime, long long packOffset, long long packTrack, const char * packData, long long packDataSize, uint64_t packBytePos, bool isKeyframe){
null(); null();
master = true; master = true;
//time and trackID are part of the 20-byte header. //time and trackID are part of the 20-byte header.
@ -1167,9 +1167,9 @@ namespace DTSC {
///\brief Updates a track and its metadata given new packet properties. ///\brief Updates a track and its metadata given new packet properties.
///Will also insert keyframes on non-video tracks, and creates fragments ///Will also insert keyframes on non-video tracks, and creates fragments
/*LTS /*LTS
void Track::update(long long packTime, long long packOffset, long long packDataSize, long long packBytePos, bool isKeyframe, long long packSendSize, unsigned long segment_size) { void Track::update(long long packTime, long long packOffset, long long packDataSize, uint64_t packBytePos, bool isKeyframe, long long packSendSize, unsigned long segment_size) {
LTS*/ LTS*/
void Track::update(long long packTime, long long packOffset, long long packDataSize, long long packBytePos, bool isKeyframe, long long packSendSize, unsigned long segment_size, const char * iVec) { void Track::update(long long packTime, long long packOffset, long long packDataSize, uint64_t packBytePos, bool isKeyframe, long long packSendSize, unsigned long segment_size, const char * iVec) {
if ((unsigned long long)packTime < lastms) { if ((unsigned long long)packTime < lastms) {
static bool warned = false; static bool warned = false;
if (!warned){ if (!warned){
@ -1298,7 +1298,7 @@ namespace DTSC {
///\brief Returns a key given its number, or an empty key if the number is out of bounds ///\brief Returns a key given its number, or an empty key if the number is out of bounds
Key & Track::getKey(unsigned int keyNum) { Key & Track::getKey(unsigned int keyNum) {
static Key empty; static Key empty;
if (keyNum < keys[0].getNumber()) { if (!keys.size() || keyNum < keys[0].getNumber()) {
return empty; return empty;
} }
if ((keyNum - keys[0].getNumber()) > keys.size()) { if ((keyNum - keys[0].getNumber()) > keys.size()) {
@ -1320,11 +1320,13 @@ namespace DTSC {
} }
/// Gets indice of the fragment containing timestamp, or last fragment if nowhere. /// Gets indice of the fragment containing timestamp, or last fragment if nowhere.
unsigned int Track::timeToFragnum(unsigned int timestamp){ uint32_t Track::timeToFragnum(uint64_t timestamp){
for (unsigned int i = 0; i<fragments.size(); i++){ uint32_t i = 0;
if (timestamp <= getKey(fragments[i].getNumber()).getTime() + fragments[i].getDuration()){ for (std::deque<Fragment>::iterator it = fragments.begin(); it != fragments.end(); ++it){
if (timestamp < getKey(it->getNumber()).getTime() + it->getDuration()){
return i; return i;
} }
++i;
} }
return fragments.size()-1; return fragments.size()-1;
} }
@ -1404,9 +1406,9 @@ namespace DTSC {
///\brief Updates a meta object given a JSON::Value ///\brief Updates a meta object given a JSON::Value
void Meta::update(JSON::Value & pack, unsigned long segment_size) { void Meta::update(JSON::Value & pack, unsigned long segment_size) {
/*LTS /*LTS
update(pack["time"].asInt(), pack.isMember("offset")?pack["offset"].asInt():0, pack["trackid"].asInt(), pack["data"].asStringRef().size(), pack.isMember("bpos")?pack["bpos"].asInt():-1, pack.isMember("keyframe"), pack.packedSize(), segment_size); update(pack["time"].asInt(), pack.isMember("offset")?pack["offset"].asInt():0, pack["trackid"].asInt(), pack["data"].asStringRef().size(), pack.isMember("bpos")?pack["bpos"].asInt():0, pack.isMember("keyframe"), pack.packedSize(), segment_size);
LTS*/ LTS*/
update(pack["time"].asInt(), pack.isMember("offset")?pack["offset"].asInt():0, pack["trackid"].asInt(), pack["data"].asStringRef().size(), pack.isMember("bpos")?pack["bpos"].asInt():-1, pack.isMember("keyframe"), pack.packedSize(), segment_size, pack.isMember("ivec")?pack["ivec"].asStringRef().data():0); update(pack["time"].asInt(), pack.isMember("offset")?pack["offset"].asInt():0, pack["trackid"].asInt(), pack["data"].asStringRef().size(), pack.isMember("bpos")?pack["bpos"].asInt():0, pack.isMember("keyframe"), pack.packedSize(), segment_size, pack.isMember("ivec")?pack["ivec"].asStringRef().data():0);
} }
///\brief Updates a meta object given a DTSC::Packet ///\brief Updates a meta object given a DTSC::Packet
@ -1418,13 +1420,13 @@ namespace DTSC {
unsigned int ivecLen; unsigned int ivecLen;
pack.getString("ivec", ivec, ivecLen); pack.getString("ivec", ivec, ivecLen);
/*LTS /*LTS
update(pack.getTime(), pack.hasMember("offset")?pack.getInt("offset"):0, pack.getTrackId(), dataLen, pack.hasMember("bpos")?pack.getInt("bpos"):-1, pack.hasMember("keyframe"), pack.getDataLen(), segment_size); update(pack.getTime(), pack.hasMember("offset")?pack.getInt("offset"):0, pack.getTrackId(), dataLen, pack.hasMember("bpos")?pack.getInt("bpos"):0, pack.hasMember("keyframe"), pack.getDataLen(), segment_size);
LTS*/ LTS*/
update(pack.getTime(), pack.hasMember("offset")?pack.getInt("offset"):0, pack.getTrackId(), dataLen, pack.hasMember("bpos")?pack.getInt("bpos"):-1, pack.hasMember("keyframe"), pack.getDataLen(), segment_size, ivecLen?ivec:0); update(pack.getTime(), pack.hasMember("offset")?pack.getInt("offset"):0, pack.getTrackId(), dataLen, pack.hasMember("bpos")?pack.getInt("bpos"):0, pack.hasMember("keyframe"), pack.getDataLen(), segment_size, ivecLen?ivec:0);
} }
///\brief Updates a meta object given a DTSC::Packet with byte position override. ///\brief Updates a meta object given a DTSC::Packet with byte position override.
void Meta::updatePosOverride(DTSC::Packet & pack, unsigned long bpos) { void Meta::updatePosOverride(DTSC::Packet & pack, uint64_t bpos) {
char * data; char * data;
unsigned int dataLen; unsigned int dataLen;
pack.getString("data", data, dataLen); pack.getString("data", data, dataLen);
@ -1437,7 +1439,7 @@ namespace DTSC {
update(pack.getTime(), pack.hasMember("offset")?pack.getInt("offset"):0, pack.getTrackId(), dataLen, bpos, pack.hasMember("keyframe"), pack.getDataLen(), 5000, ivecLen?ivec:0); update(pack.getTime(), pack.hasMember("offset")?pack.getInt("offset"):0, pack.getTrackId(), dataLen, bpos, pack.hasMember("keyframe"), pack.getDataLen(), 5000, ivecLen?ivec:0);
} }
void Meta::update(long long packTime, long long packOffset, long long packTrack, long long packDataSize, long long packBytePos, bool isKeyframe, long long packSendSize, unsigned long segment_size, const char * ivec){ void Meta::update(long long packTime, long long packOffset, long long packTrack, long long packDataSize, uint64_t packBytePos, bool isKeyframe, long long packSendSize, unsigned long segment_size, const char * ivec){
DONTEVEN_MSG("Updating meta with: t=%lld, o=%lld, s=%lld, t=%lld, p=%lld", packTime, packOffset, packDataSize, packTrack, packBytePos); DONTEVEN_MSG("Updating meta with: t=%lld, o=%lld, s=%lld, t=%lld, p=%lld", packTime, packOffset, packDataSize, packTrack, packBytePos);
if (!packSendSize){ if (!packSendSize){
//time and trackID are part of the 20-byte header. //time and trackID are part of the 20-byte header.
@ -1448,7 +1450,10 @@ namespace DTSC {
//data adds packDataSize+5 bytes (string type) and 6 bytes (2+namelen) //data adds packDataSize+5 bytes (string type) and 6 bytes (2+namelen)
packSendSize = 24 + (packOffset?17:0) + (packBytePos>=0?15:0) + (isKeyframe?19:0) + packDataSize+11; packSendSize = 24 + (packOffset?17:0) + (packBytePos>=0?15:0) + (isKeyframe?19:0) + packDataSize+11;
} }
vod = (packBytePos >= 0); if (vod != (packBytePos > 0)){
INFO_MSG("Changing stream from %s to %s (bPos=%lld)", vod?"VoD":"live", (packBytePos >= 0)?"Vod":"live", packBytePos);
}
vod = (packBytePos > 0);
live = !vod; live = !vod;
if (packTrack > 0 && tracks.count(packTrack)){ if (packTrack > 0 && tracks.count(packTrack)){
tracks[packTrack].update(packTime, packOffset, packDataSize, packBytePos, isKeyframe, packSendSize, segment_size, ivec); tracks[packTrack].update(packTime, packOffset, packDataSize, packBytePos, isKeyframe, packSendSize, segment_size, ivec);
@ -2022,6 +2027,63 @@ namespace DTSC {
it->second.reset(); it->second.reset();
} }
} }
PartIter::PartIter(Track & Trk, Fragment & frag){
tRef = &Trk;
pIt = tRef->parts.begin();
kIt = tRef->keys.begin();
uint32_t fragNum = frag.getNumber();
while (kIt->getNumber() < fragNum && kIt != tRef->keys.end()){
uint32_t kParts = kIt->getParts();
for (uint32_t pCount = 0; pCount < kParts && pIt != tRef->parts.end(); ++pCount){
++pIt;
}
++kIt;
}
if (kIt == tRef->keys.end()){tRef = 0;}
currInKey = 0;
lastKey = fragNum + frag.getLength();
}
/// Dereferences into a Value reference.
/// If invalid iterator, returns an empty reference and prints a warning message.
Part & PartIter::operator*() const{
if (tRef && pIt != tRef->parts.end()){
return *pIt;
}
static Part error;
WARN_MSG("Dereferenced invalid Part iterator");
return error;
}
/// Dereferences into a Value reference.
/// If invalid iterator, returns an empty reference and prints a warning message.
Part* PartIter::operator->() const{
return &(operator*());
}
/// True if not done iterating.
PartIter::operator bool() const{
return (tRef && pIt != tRef->parts.end());
}
PartIter & PartIter::operator++(){
if (*this){
++pIt;
if (++currInKey >= kIt->getParts()){
currInKey = 0;
//check if we're done iterating - we assume done if past the last key or arrived past the fragment
if (++kIt == tRef->keys.end() || kIt->getNumber() >= lastKey){
tRef = 0;
}
}
}
return *this;
}
} }

View file

@ -696,7 +696,7 @@ void HTTP::Parser::Chunkify(const char * data, unsigned int size, Socket::Connec
if (sendingChunks) { if (sendingChunks) {
//prepend the chunk size and \r\n //prepend the chunk size and \r\n
if (!size){ if (!size){
conn.SendNow("0\r\n\r\n\r\n", 7); conn.SendNow("0\r\n\r\n", 5);
} }
size_t offset = 8; size_t offset = 8;
unsigned int t_size = size; unsigned int t_size = size;